我可以期待在结构数组什么对齐保证?
题
我有一个包含几个成员的对象是很少用一个轻量级的模板类,所以我想避免调用它们的构造函数和析构函数除了在极少数情况下,当我实际使用它们。
要做到这一点,我在我的课这样的“声明”他们:
template <class K, class V> class MyClass
{
public:
MyClass() : wereConstructorsCalled(false) {/* empty */}
~MyClass() {if (wereConstructorsCalled) MyCallPlacementDestructorsFunc();}
[...]
private:
bool wereConstructorsCalled;
mutable char keyBuf[sizeof(K)];
mutable char valBuf[sizeof(V)];
};
...然后我使用新的布局和位置删除,只建立和拆除的对象时,我真的需要这么做。
阅读C ++ FAQ有人说,用放置新的时候,我需要小心的是,放置是否正确设置,否则我就遇到了麻烦。
我的问题是,将keyBuf和valBuf阵列在所有情况下正确对齐,或者是有一些额外的步骤,我需要确保他们正确对齐? (如果是的话,非平台相关的步骤将是优选的)
解决方案
有没有保证,你会得到适当的定位。阵列一般仅保证成员类型对齐。甲char
阵列被对准为char
的存储。
一个例外是用char
分配的unsigned char
和new
阵列给定的最大对齐,这样就可以任意类型存储到它们。但正如你避免堆分配这个保证不你的情况适用。
TR1和的C ++ 0x添加一些非常有用的类型,但:
和std::alignment_of
一起std::aligned_storage
给你一个便携式(和功能)的答案。
std::alignment_of<T>::value
给你一个类型T
所需的对准。 std::aligned_storage<A, S>::type
为您提供了对准A
和大小S
一个POD类型。这意味着,你可以放心地写你的对象变成类型std::aligned_storage<A, S>::type
的变量。
(在TR1,命名空间是std::tr1
,而不是仅仅std
)
其他提示
我可以问你为什么要他们放到一个字符缓冲区?为什么不创建K和V的指针对象然后实例化它,当你需要它。
也许我不明白你的问题,但你不能只是char *keyBuf[..size..];
,最初将其设置为NULL(未分配),并分配它的第一次,你需要它吗?
什么您想与安置新做似乎风险的业务和不良的编码风格。
反正代码对准是依赖于实现的。
如果你想改变的代码比对使用编译包
#pragma pack(push,x)
// class code here
#pragma pack(pop) // to restore original pack value
如果x为1,将有您的元素之间没有填充。
下面有一个链接来读取
我发现这个答复SiCrane张贴在的http:// WWW .gamedev.net /小区/论坛/ topic.asp topic_id = 455233 :
然而,对于静态分配,它减少浪费申报存储器块与其它类型的联合。那么存储器块将被保证被对准以在联合最严格的类型的对准。这仍然是相当丑陋的两种方式。
听起来像是一个联盟可能做的伎俩!
我建议你看看boost::optional
模板。它做你需要什么,即使你不能使用它你应该看一下它的实现。
它使用alignment_of
和type_with_alignment
其对准的计算和担保。
要做出一个很很长的故事非常非常短,这是不会帮你的任何性能,将导致大量的头痛,它会不会是你卷入编写自己的内存managemer很久以前。
放置新的优良的POD(但也救不了你任何东西),但如果你有一个构造函数都那么它不会在所有的工作。
您也不能依赖于你的布尔变量的值,如果使用新的位置。
展示位置新建了用途,但不能真正完成这个。