2012-07-03 123 views
1

是否有可能使用malloc将某些参数传递给另一个类的构造函数中的某个类的构造函数?我可以用new来做到这一点。我需要做同样的事情malloc: (如果它没有任何意义,认为我使用的是自定义分配器代替的malloc)malloc和C++构造函数

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)); 
     ??????????????? } 
} 
+1

* B = B_Class(C1,C2,C3); –

+1

你为什么要'malloc'超过'new'? –

+0

它实际上是一个自定义分配器。我使用了“malloc”来使问题更加明智。 –

回答

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); 

P.S.您可能会考虑采用不同的路线:在您的班级中超载operator new/operator delete,而不是在每次需要创建对象时都明确指定自定义分配。

+0

谢谢安德烈。它不是为raw_b分配一个新的内存吗?你确定这样raw_b使用在第一行分配的内存? –

+0

@Amir Reza:是的,那是标准特征的全部重点。这种特定形式的放置新的确如此:在预先分配的内存中的给定位置构造对象。 – AnT

+1

除了避免强制转换之外,'void *'指针的另一个优点是,如果从'new'的结果中获得了'B_Class *',那么您就不会因为指向B_Class实际上指向实际的'B_Class'对象。 –

0

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

+0

谢谢James。当然,它不会调用构造函数。但是为什么在分配内存之后我不能传递参数?像什么“新”本身。 –

+0

因为即使在分配内存之后,您仍未调用任何构造函数。您可以将参数传递给构造函数的唯一方法是使用new运算符。 (如果您已将初始化分配分配,或者使用自定义运算符新分配,则可能会放置新的。) –

2

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

在C++ 03中,这只能进行复制构建,因此您必须致电allocator.construct(ptr, B_Class(c1, c2, c3))并且该类必须是可复制的。在C++ 11中,分配器可以从任何参数构造。

如果您的分配器是为C设计的,那么您将不得不使用所谓的“放置新”。当然,malloc是专为C.你应该看看它自己,但语法是:

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

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

+0

您可能需要'#include '放置新的 – Pierre

+0

@Pierre:true。我说“自己查看”的一部分原因是,我非常少用它,以至于我自己都记不清细节。我比我听说过的提问者有优势! –

+0

只是评论别担心:) – Pierre

0

可以用于构建乙创建静态方法:

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