我有一个包含几个成员的对象是很少用一个轻量级的模板类,所以我想避免调用它们的构造函数和析构函数除了在极少数情况下,当我实际使用它们。

要做到这一点,我在我的课这样的“声明”他们:

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 charnew阵列给定的最大对齐,这样就可以任意类型存储到它们。但正如你避免堆分配这个保证不你的情况适用。

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,将有您的元素之间没有填充。

下面有一个链接来读取

http://www.cplusplus.com/forum/general/14659/

我发现这个答复SiCrane张贴在的http:// WWW .gamedev.net /小区/论坛/ topic.asp topic_id = 455233

  

然而,对于静态分配,它减少浪费申报存储器块与其它类型的联合。那么存储器块将被保证被对准以在联合最严格的类型的对准。这仍然是相当丑陋的两种方式。

听起来像是一个联盟可能做的伎俩!

我建议你看看boost::optional模板。它做你需要什么,即使你不能使用它你应该看一下它的实现。

它使用alignment_oftype_with_alignment其对准的计算和担保。

要做出一个很很长的故事非常非常短,这是不会帮你的任何性能,将导致大量的头痛,它会不会是你卷入编写自己的内存managemer很久以前。

放置新的优良的POD(但也救不了你任何东西),但如果你有一个构造函数都那么它不会在所有的工作。

您也不能依赖于你的布尔变量的值,如果使用新的位置。

展示位置新建了用途,但不能真正完成这个。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top