什么是"新(和可变)价值;" 在C++中呢?

MrM*_*age 17 c++ operators new-operator

假设我在C++程序中有以下代码:

Object a = Object(someParameters);
new (&a) Object(someOtherParameters);
Run Code Online (Sandbox Code Playgroud)

我的假设是它取代了awith 的内容Object(someOtherParameters),避免了可能的operator=声明Object.它是否正确?

Arm*_*yan 21

它被称为安置.它会在指定的内存上调用构造函数,而不是分配新的内存.请注意,在这种情况下,您必须在释放分配的内存之前显式调用对象的析构函数.

澄清.假设您已经分配了一些原始内存

char * rawMemory = new char [sizeof (Object)];
Run Code Online (Sandbox Code Playgroud)

并且您想在该内存上构造一个对象.你打电话

new(rawMemory) Object(params);
Run Code Online (Sandbox Code Playgroud)

现在,在释放内存之前

delete [] rawMemory; 
Run Code Online (Sandbox Code Playgroud)

你必须明确地调用Object的derstuctor

reinterpret_cast<Object*>(rawMemory)->~Object();
Run Code Online (Sandbox Code Playgroud)

但是,在您的特定示例中,潜在的问题是您在内存中构造新对象之前未正确销毁现有对象.

奖励:有 没有想过std::vector如果没有包含的对象可以默认构建,标准怎么办?原因在于,大多数(如果不是全部)实现allocator<T>都不存储T* p哪一个需要T在默认情况下是可构造的p = new T[N].相反,它存储char指针 - 原始内存,并分配p = new char[N*sizeof(T)].当你push_back是一个对象时,它只是在该char数组中的适当地址上调用带有placement new的复制构造函数.

  • @KonradRudolph:不,不是.`Class*object = new(rawMemory)Class(params);`你以后不能调用`delete object;`因为内存没有被普通的`new`分配.因此,在调用`delete [] rawMemory`之前,必须显式调用`object-> ~Class()`. (2认同)
  • 回答和Konrad的评论都没有解决它是完全没问题(根据标准,在代码审查中好运)如果程序不依赖于析构函数的副作用,则不要调用析构函数调用放置new和新对象之前的对象. (2认同)

Pet*_*ker 6

它被称为placement new:它Object在括号内给出的地址构造new .Placement new通常用于在原始内存中创建对象.正如此代码所做的那样,在现有对象之上构造一个新对象是一个坏主意,因为它不会在原始对象上调用析构函数.