new operator、operator new 、placement new三者之間的區別與聯繫

new operator、operator new 、placement new三者之間的區別與聯繫


1. new的執行過程:

1)通過operator new申請內存

2)使用placement new調用構造函數(簡單類型忽略此步)

3)返回內存指針

 

2. newmalloc的比較:

1new失敗時會調用new_handler處理函數,malloc不會,失敗時返回NULL

2new能通過placement new自動調用對象的構造函數,malloc不會

3new出來的東西是帶類型的,mallocvoid*,需要強制轉換

4newC++運算符,mallocC標準庫函數

 

3. delete的執行過程:

1)調用析構函數(簡單類型忽略此步)

2)釋放內存

 

4.deletefree的比較

1delete能自動調用對象的析構函數,malloc不會

2deleteC++運算符,freeC標準庫函數

 

5. new的三種形態:new operator,operator new, placement new

1new operator

上面所說的new就是new operator,共有三個步驟組成(申請內存,調用構造函數,返回內存指針),對於申請內存步驟是通過運算符new(operator new)完成的,對於調用什麼構造函數,可以由placement new決定。

2operator new

像普通運算符一樣可以被重載,operator new會去申請內存,申請失敗的時候會調用new_handler處理,這是一個循環的過程,如果new_handler不拋出異常,會一直循環申請內存,直到成功。

重載operator new(注意:正像new delete 一一對應一樣,operatornewoperatordelete 也是一一對應的;如果重載了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。但是通

常情況下不建議使用,除非是在某些對時間要求非常高的應用中,因爲相對於其他兩

個步驟,選擇合適的構造函數完成對象初始化是一個時間相對較長的過程。

發佈了50 篇原創文章 · 獲贊 10 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章