new (this) ThisClass() 是个坏主意吗?
Is new (this) ThisClass() a bad idea?
class FooView final : public Something
{
...
void refresh()
{
this->~FooView();
new (this) FooView();
}
}
我从来没有见过这个成语,看起来它可能真的很微妙和混乱,但我实际上想不出它有什么问题(只要 FooView
是最终的)。这是个坏主意吗?
你可以这样做,但如果你有引用或 const 成员,或者 class 的类型发生变化,你将需要为此进行内存清洗。
考虑一下:
struct FooView {
const int val;
void refresh()
{
this->~FooView();
new (this) FooView{5};
}
}
int main() {
FooView fv{9};
std::cout << fv.val; // surely 9!
fv.refresh();
std::cout << fv.val; // hmm... val is a const object, so it's 9 still?
}
为避免这种未定义的行为,您应该使用 std::launder
清理内存。编译器会假定 fv
的生命周期不会受到除 }
之外的任何影响。洗钱将使编译器假设有一个与 fv
:
无关的对象
int main() {
FooView fv{9};
std::cout << fv.val; // surely 9!
fv.refresh();
std::cout << std::launder(&fv)->val; // yay, 5
}
现在是个好主意吗?我建议不要这样做,因为它会导致混乱,但可以安全地完成。
class FooView final : public Something
{
...
void refresh()
{
this->~FooView();
new (this) FooView();
}
}
我从来没有见过这个成语,看起来它可能真的很微妙和混乱,但我实际上想不出它有什么问题(只要 FooView
是最终的)。这是个坏主意吗?
你可以这样做,但如果你有引用或 const 成员,或者 class 的类型发生变化,你将需要为此进行内存清洗。
考虑一下:
struct FooView {
const int val;
void refresh()
{
this->~FooView();
new (this) FooView{5};
}
}
int main() {
FooView fv{9};
std::cout << fv.val; // surely 9!
fv.refresh();
std::cout << fv.val; // hmm... val is a const object, so it's 9 still?
}
为避免这种未定义的行为,您应该使用 std::launder
清理内存。编译器会假定 fv
的生命周期不会受到除 }
之外的任何影响。洗钱将使编译器假设有一个与 fv
:
int main() {
FooView fv{9};
std::cout << fv.val; // surely 9!
fv.refresh();
std::cout << std::launder(&fv)->val; // yay, 5
}
现在是个好主意吗?我建议不要这样做,因为它会导致混乱,但可以安全地完成。