std::make_shared
和 new
都用於動態分配內存並返回指向該內存的指針,但它們之間有一些重要的區別。下面詳細解釋它們之間的差異:
-
內存分配方式:
std::make_shared
:該函數是一個模板函數,會在內存中分配一塊足夠大的內存來存儲對象及其控制塊(用於跟蹤引用計數等信息),然後在此內存上構造對象。因此,std::make_shared
一次性完成了內存分配和對象構造。new
:使用new
運算符動態分配內存時,會首先分配足夠的內存來存儲對象,並返回指向該內存的指針。然後,必須顯式地調用構造函數來在該內存上構造對象。
-
性能:
std::make_shared
通常比直接使用new
更高效,因爲它只需一次內存分配和一次構造函數調用。而使用new
則需要兩次內存分配(對象內存和控制塊內存)和一次構造函數調用。- 另外,
std::make_shared
還可以減少內存碎片化,因爲它在一次分配中爲對象和控制塊分配了連續的內存。
-
異常安全性:
std::make_shared
在內存分配和對象構造過程中提供了強異常安全性。如果在分配內存或構造對象時拋出異常,std::make_shared
會自動處理已分配的內存,確保沒有內存泄漏,並且不會部分構造對象。- 使用
new
時,如果在分配內存後拋出異常,可能會導致內存泄漏,因爲在異常拋出前分配的內存無法釋放。
-
代碼簡潔性:
std::make_shared
可以使代碼更加簡潔,因爲它結合了內存分配和對象構造,並且不需要指定對象的類型(由模板參數推導)。- 使用
new
時,需要顯式地指定對象類型,並且需要兩步操作:分配內存和構造對象。
綜上所述,優先使用 std::make_shared
來動態分配對象,因爲它在性能、異常安全性和代碼簡潔性方面都有優勢。只有在特定情況下(例如需要控制對象和控制塊的內存分配)才考慮使用 new
。