放置 new 以规避赋值构造函数

问题描述

使用 placement new 来规避复制分配是否可行?

我有一个包含 const 成员的成员对象。 对象本身应该在运行时创建,但它的成员应该是常量。

我想知道我是否可以在运行时使用 placement new 来规避复制分配?

#include <new>
#include <iostream>
struct A {
    const int a;
    A() : a(0) {};
    A(int a) : a(a){}
};

struct B {
    A a;
    void createA() {
        new(&a) A(69);
    }

    void useA() {
        std::cout << a.a << std::endl;
    }

};

int main(void) {

    B b;
    b.createA();
    b.useA();
    return 0;
}

它可以编译并运行,但它会调用 UB 吗?

解决方法

您不应该这样做,尽管在这种情况下它在技术上是可行的。

通过绕过复制分配,您不会让对象有机会对旧数据执行任何所需的清理(例如释放内存资源)。在此示例中,您将在 a 的生命周期结束之前调用新的放置运算符。

以下将起作用,因为它不会违反 a 的生命周期:

a.~A(); // manually destruct a,end it's lifetime
new(&a) A(69); // construct a new instance and start a new lifetime