显式构造函数调用

7
我想知道是否有一种技巧可以使用对象指针显式调用构造函数。如果这是合法的语法,它将如下所示:
Foo *p = malloc( sizeof(Foo) );

p->Foo::Foo();

附言:我知道我可以使用Foo *p = new Foo();,但是有一个严重的原因需要显式地使用malloc()。

@John:我想知道你所说的原因:), new 底层可能使用的是 malloc,那么为什么要费心呢? - Matthieu M.
5个回答

17
你可以使用"placement new"运算符来实现这个功能:
Foo *buf = malloc( sizeof(Foo) );
Foo *p = new (buf) Foo();

3
不要忘记,如果您手动创建它,也应该手动销毁它。 - Martin York
10
还需要注意的是,在这种情况下,你还需要显式调用析构函数:p->~Foo();(不能使用delete p)。 - Michael Burr

9

使用放置 new

Foo* p = new(malloc(sizeof(Foo))) Foo;

(不考虑任何内存不足检查)

基本上,new(address) Foo()在指针变量 address 指向的位置构造一个类型为Foo的对象,也就是说:它调用了构造函数。


3
您可以使用就地新建(placement new)在某个地址上构造新对象。
void *buf = malloc(sizeof(Foo)); 
Foo *p = new (buf) Foo();

您可以在维基百科关于它的文章中了解更多信息。

3

其他人已经指出,您可以使用放置new。如果您希望类的某些特定对象位于使用malloc分配的内存中,则这很有效。正如也已经指出的那样,当您这样做时,需要显式调用dtor。

如果您希望类的所有对象都在使用malloc分配的内存中,则可以为该类重载operator new(和operator delete),并让它们调用malloc以获取原始内存。这减轻了客户端代码分别分配/初始化的额外步骤。

如果您希望集合中的所有对象(或多个集合中的所有对象)都在使用malloc分配的内存中,则可以向该集合提供一个分配器来实现。同样,这减轻了客户端代码处理分配的负担,并使容器看起来、行为和“感觉”像一个普通容器。


0
    struct MyClass
    {
            MyClass()
            {
                    std::cout << "ctor" << std::endl;
            }
            ~MyClass()
            {
                    std::cout << "dtor" << std::endl;
            }
    };

    int main(int argc, char *argv[])
    {
            // Allocate memory and call constructor
            MyClass myObj;

            // Call constructor again with placement new
            new (&myObj) MyClass;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接