2012-07-03 128 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; 
    } 
....