Hos*_*ork 13 c++ placement-new undefined-behavior language-lawyer
(注意:这个问题的动机是试图提出预处理器hackery来生成无操作分配来回答这个问题:
......所以请记住!)
这是一个人为的课程:
class foo {
private:
int bar;
public:
foo(int bar) : bar (bar)
{ std::cout << "construct foo #" << bar << std::endl; }
~foo()
{ std::cout << "destruct foo #" << bar << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
......我将这样分配:
// Note: for alignment, don't use char* buffer with new char[sizeof(foo)] !
void* buffer = operator new(sizeof(foo));
foo* p1 = new (buffer) foo(1);
foo* p2 = new (buffer) foo(2);
/* p1->~foo(); */ /* not necessary per spec and problematic in gen. case */
p2->~foo();
Run Code Online (Sandbox Code Playgroud)
在gcc上我已经到了,我得到了"预期"的结果:
construct foo #1
construct foo #2
destruct foo #2
Run Code Online (Sandbox Code Playgroud)
哪个好,但是编译器/运行时可能会拒绝这个滥用并仍然在规范的右侧吗?
线程怎么样?如果我们不真正关心这一类的内容(假设它只是反正一个虚拟对象),将它至少不会崩溃,如在更简单的应用程序,这种动机与POD诠释?
AnT*_*AnT 15
在相同的内存块上多次执行放置是非常好的.而且,无论听起来多么奇怪,你甚至都不需要破坏已经存在于该内存中的对象(如果有的话).该标准明确允许在3.8/4中
4程序可以通过重新使用该物体占据或通过显式调用一类型与非平凡的析构函数的对象的析构所述存储端的任何对象的寿命.对于一类型与非平凡的析构函数的目的,不要求该程序要将对象占据再利用或释放的存储之前显式调用析构函数; [...]
换句话说,您有责任考虑不为某些对象调用析构函数的后果.
但是,不允许在代码中调用析构函数两次.一旦在同一内存区域中创建了第二个对象,就可以有效地结束第一个对象的生命周期(即使您从未调用过它的析构函数).现在你只需要破坏第二个对象.