new operator、operator new 、placement new三者之間的區別與聯繫
1. new的執行過程:
(1)通過operator new申請內存
(2)使用placement new調用構造函數(簡單類型忽略此步)
(3)返回內存指針
2. new和malloc的比較:
(1)new失敗時會調用new_handler處理函數,malloc不會,失敗時返回NULL
(2)new能通過placement new自動調用對象的構造函數,malloc不會
(3)new出來的東西是帶類型的,malloc是void*,需要強制轉換
(4)new是C++運算符,malloc是C標準庫函數
3. delete的執行過程:
(1)調用析構函數(簡單類型忽略此步)
(2)釋放內存
4.delete和free的比較
(1)delete能自動調用對象的析構函數,malloc不會
(2)delete是C++運算符,free是C標準庫函數
5. new的三種形態:new operator,operator new, placement new
(1)new operator
上面所說的new就是new operator,共有三個步驟組成(申請內存,調用構造函數,返回內存指針),對於申請內存步驟是通過運算符new(operator new)完成的,對於調用什麼構造函數,可以由placement new決定。
(2)operator new
像普通運算符一樣可以被重載,operator new會去申請內存,申請失敗的時候會調用new_handler處理,這是一個循環的過程,如果new_handler不拋出異常,會一直循環申請內存,直到成功。
重載operator new(注意:正像new 與delete 一一對應一樣,operatornew和operatordelete 也是一一對應的;如果重載了operatornew,那麼也得重載對應的operatordelete。)
(3)placement new
placement new 是標準C++庫的一部分,被聲明在了頭文件<new>中,所以只有包含了這個文件,我們才能使用它。它在<new> 文件中的函數定義很簡單,如下所示:
#ifndef__PLACEMENT_NEW_INLINE
#define__PLACEMENT_NEW_INLINE
inline void *__CRTDECLoperator new(size_t, void *_Where) _THROW0()
{ // construct array withplacement at _Where
return (_Where);
}
inline void __CRTDECLoperator delete(void *, void *) _THROW0()
{ // delete if placementnew fails
}
inline void __CRTDECL operatordelete(void *) _THROW0()
{ // delete if placementnew fails
}
#endif /*__PLACEMENT_NEW_INLINE */
這就是placement new需要完成的事。細心的你可能會發現,placement new的定義與operator new聲明之間的區別:placement new的定義多一個void*參數。
當然,如果顯式地調用placement new,那麼也得本着負責任的態度顯式地調用與之對應的placement delete :p->~A();
最後總結一下:
1. 如果是在堆上建立對象,那麼應該使用 new operator,它會爲你提供最爲周全的服務。
2. 如果僅僅是分配內存,那麼應該調用operator new,但初始化不在它的工作職責之內。如果你對默認的內存分配過程不滿意,想單獨定製,重載operator new 是不二選擇。
3. 如果想在一塊已經獲得的內存裏建立一個對象,那就應該用placement new。但是通
常情況下不建議使用,除非是在某些對時間要求非常高的應用中,因爲相對於其他兩
個步驟,選擇合適的構造函數完成對象初始化是一個時間相對較長的過程。