26

我正在查看新操作符的簽名。它是:堆上內存分配的新操作符

void* operator new (std::size_t size) throw (std::bad_alloc); 

但是,當我們使用這個運營商,我們從來沒有使用演員。即

int *arr = new int; 

那麼,如何C++ void*類型的指針在這種情況下轉換爲int*。因爲,即使malloc返回一個void*,我們需要明確地使用一個強制轉換。

回答

39

operator newnew運算符之間的C++中存在非常細微的差異。 (再次閱讀...訂購是重要的!)

函數operator new是C的malloc函數的C++模擬。這是一個原始的內存分配器,其責任僅僅在於產生一個構建對象的內存塊。它不會調用任何構造函數,因爲這不是它的工作。通常,您不會看到直接在C++代碼中使用operator new;它看起來有點奇怪。例如:

void* memory = operator new(137); // Allocate at least 137 bytes 

new運算符是負責爲對象分配存儲器並調用它的構造的關鍵字。這是C++代碼中最常遇到的。當您編寫時

int* myInt = new int; 

您正在使用新運算符分配新整數。在內部,new運營商的工作大致是這樣的:

  1. 分配內存使用operator new保持請求的對象。
  2. 調用對象構造函數(如果有的話)。如果這引發異常,請使用operator delete釋放上述內存,然後傳播該異常。
  3. 返回一個指向新構造對象的指針。

因爲new運營商和operator new是獨立的,它可以使用new關鍵字來構造對象,而不實際分配的內存。例如,着名的放置新的允許您在用戶提供的內存中的任意內存地址上構建一個對象。例如:

T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer 
new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.' 

通過定義一個定製operator new功能可以讓你以這種方式使用new重載new操作;您指定分配的方式,C++編譯器會將它連接到new運算符。

如果您好奇,delete關鍵字以相同的方式工作。有一個稱爲operator delete的釋放函數負責處理內存,還有一個負責調用對象析構函數並釋放內存的delete操作符。但是,例如,operator newoperator delete可以在這些上下文之外使用,以代替C的mallocfree

+0

第二步應該是「調用對象構造函數,如果有的話拋出任何異常*,釋放上面的內存並傳播異常。 – GManNickG 2011-02-09 06:23:17

4

您將new表達式與operator new()函數混淆。當前者被編譯時,編譯器和其他東西產生對operator new()函數的調用並傳遞足夠大的尺寸來保存new表達式中提到的類型,然後返回該類型的指針。

+0

對於誰downvoted - 這個答案有什麼問題?這似乎是完全正確的。 – templatetypedef 2011-02-09 06:22:32