[英]*new is always wrong. ALWAYS
我通常很務實,但這對我來說太過分了!
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
真的嗎? 為什么不簡單:
static MyClass myLocalVariable{/*parameters*/};
最明顯的原因是,如果你沒有保留新返回的指針的副本,你就不可能在其上調用delete。
在更人性化的層面上,它會讓人們閱讀你的代碼時更少考慮你,這也不是一件好事。
我相信聲明的用戶意味着使用new分配靜態對象是危險的,因為內存最有可能被泄露。 更重要的是,您的變量不是指針而是引用,因此您永遠不會釋放new返回的內存的可能性更大(您多久刪除一次引用的地址?)。
問題不僅僅是無用的分配。
如果沒有人調用刪除,它將不會被刪除。 當然,程序結束時會釋放內存但是它的析構函數不會被調用。
比較下面代碼中使用Get()
和Get2()
的輸出:
#include <iostream>
struct A
{
~A(){std::cout << "Deleted\n";}
};
A& Get()
{
static A & a = *new A;
return a;
}
A& Get2()
{
static A a;
return a;
}
int main()
{
//Case 1
Get();
//Case 2
Get2();
}
在調用Get2
時調用Get
和Deleted
時,此程序的輸出Get2
。
換句話說,在情況1中,在程序終止時不會正確銷毀具有非平凡析構函數(例如,提交關閉文件句柄)的資源,但在情況2中將不會。
問題是raw new不指定所有權。 如果我新建一個物體並將其歸還,誰擁有它? 創建函數/對象是擁有它還是調用函數? 如果返回智能指針(std :: shared_ptr和std :: unique_ptr),則指定所有權。
不指定所有權是泄漏內存的最簡單方法之一。 即使是專業的程序員,我也是最艱難的時刻,讓人們了解所有權並使用它。 這主要是通過使用指定所有權的好類型(智能指針)來防止,只是通過現有的。
type* function(); // Unspecified ownership.
// Must be well documented and all users must read
// and follow the documentation.
std::unique_ptr<type> function(); // Calling function owns returned pointer.
// Single ownership.
std::shared_ptr<type> function(); // Calling function owns returned pointer.
// Shared ownership. Can have multiple owners.
std::weak_ptr<type> function(); // Calling function references returned pointer.
// Must lock pointer to get owned object, if not deleted.
// Shared ownership. Can have multiple owners.
這些不同類型的指針僅通過與原始指針不同的現有表達所有權。
至於new
總是錯的。 這是一個過於籠統的概括。 std::shared_ptr
是使用全局函數std::make_shared
創建的。 從C ++ 11開始,沒有std::make_unique
,但這將在C ++ 14中修復。 創建std::unique_ptr
的唯一方法是使用new並立即將指針指定給std::unique_ptr
。
還有一些地方你需要一個原始指針,並手動使用new
和delete
,但它們往往是非常低的水平,大多數程序員很少會遇到它們。
真正讓我對你的代碼感到困惑的不是你使用的是new
而是你正在取消引用指針並將它指定給引用。 幾乎不可能保證析構函數將被調用。 它也傾向於泄漏內存,但是在分配給靜態變量的情況下,它將在程序終止時解除分配,因此您不會真正關注內存泄漏。
MyClass& MyClass::MyInstance()
{
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
return myLocalVariable ;
}
我寧願創建靜態變量是按值而不是通過引用。 這可以防止將對象放在堆上。 根據MyClass
還可以允許對象從可執行文件映射到內存,而無需運行任何代碼來初始化它。
MyClass& MyClass::MyInstance()
{
static MyClass myLocalVariable(/*parameters*/);
return myLocalVariable ;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.