C++,是否可以直接调用构造函数,而不需要新的?

osg*_*sgx 51 c++ constructor placement-new

new如果我已经有对象的内存,我可以显式调用构造函数而不使用吗?

class Object1{
    char *str;
public:
    Object1(char*str1){
        str=strdup(str1);
        puts("ctor");
        puts(str);
    }
    ~Object1(){
        puts("dtor");
        puts(str);
        free(str);
    }
};

Object1 ooo[2] = {
     Object1("I'm the first object"), Object1("I'm the 2nd")
};

do_smth_useful(ooo);
ooo[0].~Object1(); // call destructor
ooo[0].Object1("I'm the 3rd object in place of first"); // ???? - reuse memory
Run Code Online (Sandbox Code Playgroud)

unw*_*ind 76

有点.您可以使用placement new来使用已分配的内存来运行构造函数:

 #include <new>

 Object1 ooo[2] = {Object1("I'm the first object"), Object1("I'm the 2nd")};
 do_smth_useful(ooo);
 ooo[0].~Object1(); // call destructor

 new (&ooo[0]) Object1("I'm the 3rd object in place of first");
Run Code Online (Sandbox Code Playgroud)

因此,您仍在使用new关键字,但不会进行内存分配.

  • 此外,请注意,如果构造函数抛出,灾难将会发生.该对象将保持未初始化状态,但是将来仍会在某个时刻调用析构函数. (11认同)
  • 是的,直接析构函数调用实际上是必要的,以允许对象释放任何资源,然后用新构造的对象覆盖对象. (3认同)
  • 顶部不应该有一个很大的"是",这是误导性的 (2认同)

Mic*_*fik 15

我想你正在寻找Placement New.在C++ FAQ精简版有你如何做一个很好的总结.这个条目有一些重要的问题:

  1. 您应该#include <new>使用放置新语法.
  2. 您的内存缓冲区需要与正在创建的对象正确对齐.
  3. 手动调用析构函数是你的工作.

  • @ Steve314:C++语法为`new`提供了参数,这些参数被传递给`operator new`的匹配重载.您需要库来提供所需的重载,`operator new(size_t,void*)`. (6认同)
  • 我不知道需要调用`operator new` - 我已经分配了内存,我认为placement new只是调用构造函数.我当然一直在逃避而不用担心这一点,但是(1)我可能在某处包含了`<new>`,并且(2)我的编译器总是可以让我顽皮地拿走一些东西.我想是时候复习一下,看看我做错了什么. (2认同)
  • 它调用标准库中为您定义的new替换运算符,该运算符不分配任何内存,它仅返回您传递给它的内存。然后像往常一样调用构造函数,从而实现所需的功能。这不是真正的语法,它是一个重新定义的运算符,它实际上只是返回了额外的参数 (2认同)

Cth*_*utu 15

让我向您展示一些如何在构造和破坏方面完成的代码

#include <new>

// Let's create some memory where we will construct the object.
MyObject* obj = (MyObject*)malloc(sizeof(MyObject));

// Let's construct the object using the placement new
new(obj) MyObject();

// Let's destruct it now
obj->~MyObject();

// Let's release the memory we used before
free(obj);
obj = 0;
Run Code Online (Sandbox Code Playgroud)

我希望上面的总结能让事情更加清晰.


Ben*_*igt 5

从字面上讲,不,没有"新"关键字,你不能这样做.有关使用"new"关键字调用构造函数而不实际分配内存的方法,请参阅有关placement new的所有答案.