c ++中的malloc和构造函数

时间:2012-07-03 14:50:56

标签: c++ constructor malloc new-operator

是否可以使用malloc将一些参数传递给另一个类的构造函数中的类的构造函数?我可以用new做到这一点。我需要对malloc做同样的事情: (如果没有意义,请考虑我使用自定义分配器而不是malloc)

Class A_Class ... {
       public:
       B_Class *b;
...
     A_Class: ...
      { b = new B_Class (c1, c2, c3);
      } // end of constructor
}

现在使用malloc:

Class A_Class ... {
       public:
       B_Class *b;
...
     A_Class: ...
      { b = (B_Class*) malloc (sizeof(*b)); 
        ??????????????? }
}

4 个答案:

答案 0 :(得分:9)

malloc分配原始内存。尝试将构造函数参数传递给它是没有意义的,因为它不会调用任何构造函数。

如果必须使用原始内存,则可以使用“placement new”语法在先前分配的原始内存中构造对象

...
void *raw_b = malloc(sizeof *b);
b = new(raw_b) B_Class(c1, c2, c3); // <- placement new 
...

在数值上,b的值将与raw_b相同,即可以在没有额外raw_b指针的情况下使用。但我更喜欢这样做,使用中间void *指针,以避免丑陋的演员。

当然,在销毁这些物品时要小心。自定义分配需要自定义删除在一般情况下,您不能delete b b->~B_Class(); // <- explicit destructor call free(b); 。对称的自定义删除序列将涉及显式析构函数调用,然后是原始内存释放

operator new

P.S。您可能会考虑采用不同的路线:在您的类中重载operator delete / {{1}},而不是在每次需要创建对象时明确拼写自定义分配。

答案 1 :(得分:2)

不,这是不可能的。如果它是为C ++设计的,那么你的自定义分配器将有一个名为construct的函数用于此(和rebind以获得可以构造不同类型的分配器。)

在C ++ 03中,这只是复制构造,所以你必须调用allocator.construct(ptr, B_Class(c1, c2, c3))并且该类必须是可复制的。在C ++ 11中,分配器可以从任何参数构造。

如果您的分配器是为C设计的,那么您将不得不使用所谓的“placement new”。当然,malloc是为C设计的。您应该自己查找,但语法是:

b = (B_Class*) malloc(sizeof(*b));
new ((void*)b) B_Class(c1,c2,c3);

请记住处理构造函数可能抛出的任何异常,并free缓冲区。

答案 2 :(得分:0)

malloc不会调用构造函数。没有办法将参数传递给不会被调用的函数。至于自定义分配器,您必须更具体地了解您正在做什么。谁在分配使用自定义分配器的位置。通常,自定义分配器仅用于分配;他们也不关心构造函数。

答案 3 :(得分:0)

您可以创建静态方法来构建B:

class B_Class
{
     public static B_Class* MallocMe(SomeParam param)
     {
           B_Class* retval = (B_Class*) malloc(sizeof(B_Class));
           retval->Construct(param);
           return retval;
     }
 ....