我有两节课:
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;
在我的代码的总和中“容器”对象的唯一用法是用于初始化“ArrayToUse”类的对象,如上所述,在“charArray”引用“temp.container.charArray”之后,我将使用它在我的其余代码中引用,现在我想知道编译器为“容器”对象保留内存,因为它有临时用法吗?
答案 0 :(得分:2)
在全局范围定义的任何变量都在编译时为其保留了内存。这并不意味着它可以保证正确初始化,但它们都是一样的。
在链接时,Visual C ++提供strip unused data and functions via /OPT的选项 - 请参阅此处。
答案 1 :(得分:0)
它完全取决于你的特定编译器所以我会说检查程序集并找出答案! 编译器可以优化容器,或者可以忽略这样做。
答案 2 :(得分:0)
编译器应该在编译的目标文件中创建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的评论暗示我在这里做得太过分了。他是对的。
根据wikipedia,
- 指向POD结构的指针 物体,使用适当的转换 重新解释演员,指向它 初始成员,反之亦然, 意味着没有填充物 POD结构的开头。
所以在这种情况下,
其中charArray
是Cont<n>
的第一个成员,并且没有非POD成员
没有赋值运算符,也没有析构函数
这是安全的。