我有以下两个课程:
template <size_t size>
class Cont{
public:
char charArray[size];
};
template <size_t size>
class ArrayToUse{
public:
Cont<size> container;
inline ArrayToUse(const Cont<size+1> & input):container(reinterpret_cast<const Cont<size> &>(input)){}
};
我在全局范围内有以下三行代码:
const Cont<12> container={"hello world"};
ArrayToUse<11> temp(container);
char (&charArray)[11]=temp.container.charArray;
在我的代码整体中,“container”对象的唯一用法是初始化“ArrayToUse”类的对象,如上所述,在初始化“charArray”对“temp.container.charArray”的引用后,我将在我的其余代码,现在我想知道编译器是否为“容器”对象保留内存,因为它有临时用途?
在全局范围内定义的任何变量都会在编译时为其保留内存。这并不意味着它保证被正确初始化,但它仍然存在。
在链接时,Visual C++ 提供了选项来通过 /OPT 删除未使用的数据和函数 - 请参阅此处。
这完全取决于您的特定编译器,所以我想说检查程序集并找出答案! 编译器可以优化容器,也可以忽略这样做。
编译器应该在编译后的目标文件中创建
container
变量。 链接器可以判断是否需要它(对于 export
ed 符号,或者来自另一个编译单元,如果声明为 extern
)。
但是...
类型
Cont<x>
与Cont<x+1>
无关。 您不能依赖以类似方式布置的成员变量的内存。 哎呀,你甚至不知道它看起来是否相同,因为有一个叫做“模板专业化”的东西:
// your code
template <size_t size>
class Cont{
public:
char charArray[size];
};
// my evil tweak
// I'm the worst compiler ever but I feel that this
// array would better be represented as a map...
template<> class Cont<12> {
std::map<int,char> charArray;
};
// your screwed up result
Cont<12> c12;
Cont<11>& c11( reinterpret_cast<Cont<11>&>(c12) );
char (&s11)[11] = c11.charArray; // points to the first byte of a list object...
编辑——@UncleBen 的评论暗示我在这里做得太过分了。 他是对的。
根据维基百科,
- 指向 POD 结构体的指针 对象,使用适当转换 重新解释演员阵容,指出其 初始成员,反之亦然, 意味着没有填充 POD 结构的开始。
所以在这种情况下,
其中
charArray
是 Cont<n>
的第一个成员,并且没有非 POD 成员没有赋值运算符,也没有析构函数
很安全。