Ker*_* SB 28 c++ placement-new
有时重新开始很好.在C++中,我可以使用以下简单的操作:
{
T x(31, Blue, false);
x.~T(); // enough with the old x
::new (&x) T(22, Brown, true); // in with the new!
// ...
}
Run Code Online (Sandbox Code Playgroud)
在范围的最后,析构函数将再次运行,一切似乎都很好.(我们也说T有点特别,不喜欢被分配,更不用说交换了.)但有些东西告诉我,摧毁一切并再试一次并不总是没有风险.这种方法有可能存在吗?
Gri*_*zly 28
我认为使这个真正安全的唯一方法是要求被调用的构造函数noexcept,例如通过添加static_assert:
static_assert(noexcept(T(22, Brown, true)), "The constructor must be noexcept for inplace reconstruction");
T x(31, Blue, false);
x.~T();
::new (&x) T(22, Brown, true);
Run Code Online (Sandbox Code Playgroud)
当然这只适用于C++ 11.
Xeo*_*Xeo 17
如果T构造函数抛出第二个构造,则会出现问题.如果你喜欢蛮力方法,请检查:
T x(31, Blue, false);
x.~T();
const volatile bool _ = true;
for(;_;){
try{
::new (&x) T(22, Brown, true);
break; // finally!
}catch(...){
continue; // until it works, dammit!
}
}
Run Code Online (Sandbox Code Playgroud)
它甚至提供强大的异常保证!
更严重的是,它就像踩着地雷一样,知道如果你移动你的脚就会熄灭它...
还有其实是在这里的双重破坏的未定义行为方式:
#include <cstdlib>
T x(31, Blue, false);
x.~T();
try{
::new (&x) T(22, Brown, true);
}catch(...){
std::exit(1); // doesn't call destructors of automatic objects
}
Run Code Online (Sandbox Code Playgroud)
我试着编译它,但我只敢在调试器下运行它.所以我看看我的旧编译器生成的反汇编(注释也是编译器):
@1 sub nerve.cells, fa0h
@2 xor x, x // bitch.
@3 mov out, x
@4 test out, out
@5 jne @1
@6 xor x, x // just in case.
@7 sub money, 2BC // dammit.
@8 mov %x, new.one
@8 cmp new.one, %x
@9 jne @7
...
@25 jmp @1 // sigh...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1899 次 |
| 最近记录: |