Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 即使在同一类型上,是否应使用placement new调用析构函数_C++_Placement New - Fatal编程技术网

C++ 即使在同一类型上,是否应使用placement new调用析构函数

C++ 即使在同一类型上,是否应使用placement new调用析构函数,c++,placement-new,C++,Placement New,我所知道的是,当使用placement new时,应该始终调用析构函数。然而,在这个示例代码中,析构函数是在main的末尾隐式调用的,所以我认为再次调用它是未定义的行为。 所以现在我想知道,当使用placement new时,是否应该始终调用析构函数,或者在某些情况下不应该调用析构函数 我所知道的是,当使用placement new时,应该始终调用析构函数 是的,除非类型是可破坏的 在这种情况下,必须在放置新对象之前销毁先前构建的对象: 2 destroyed 非平凡可销毁类型的自动变量在销毁

我所知道的是,当使用placement new时,应该始终调用析构函数。然而,在这个示例代码中,析构函数是在main的末尾隐式调用的,所以我认为再次调用它是未定义的行为。 所以现在我想知道,当使用placement new时,是否应该始终调用析构函数,或者在某些情况下不应该调用析构函数

我所知道的是,当使用placement new时,应该始终调用析构函数

是的,除非类型是可破坏的

在这种情况下,必须在放置新对象之前销毁先前构建的对象:

2
destroyed
非平凡可销毁类型的自动变量在销毁状态下不得超出范围。如果构造函数抛出,则行为将是未定义的。不建议重用非平凡对象的内存

重用普通对象的内存更安全:

X x{1};
x.~X();
try {
    new (&x) X{2};
} catch(...) {
    std::abort(); // no way to recover
}

在C++标准

中明确规定 [basic.life]

程序可以通过重用 对象占用或通过显式调用 具有非平凡类的类类型的对象的析构函数 析构函数。对于具有非平凡 析构函数,程序不需要调用析构函数 在对象所占用的存储被重用或 释放;但是,如果没有显式调用析构函数或 如果未使用删除表达式释放存储,则 析构函数不应隐式调用,任何依赖于 关于析构函数产生的副作用有未定义的行为

最后一句话为未定义行为的可能性留下了一点回旋余地。但归根结底,只有那些析构函数真正微不足道的类型才是定义良好的类型


1-无论如何,在写这篇文章时。

请注意,我们为此目的提供了一个新的解决方案。或者,我更喜欢,因为从那时起,您不需要编写所有的
sizeof
alignof
操作符。(简单地编写
std::aligned_storage_t buf;
,这会很好,不是吗?;-)这意味着在重用具有非平凡dtor的类型的存储之前,最好总是调用dtor,以保证该dtor的副作用。然而,当作用域退出时,是否仍保证有一个隐式dtor调用,那么显式调用是否为UB?关于UB的部分可能会被删除。看到了吗?这意味着此时不应该在范围退出时进行显式调用,对吗?然后保证调用它。@mkmostafa-声明了一个对象,在范围出口销毁了一个对象。
X x{1};
x.~X();
try {
    new (&x) X{2};
} catch(...) {
    std::abort(); // no way to recover
}
alignas(alignof(X)) std::byte arr[sizeof(X)];
new (arr) X{2};
x.~X();