2016-09-26 91 views
1

要初始化的基準構件,而不傳遞給含類的構造的外部實體的引用,一個工廠的方法可用於,例如:自毀基準部件初始化

struct B 
{ 
    B() : a(new_a()) {} 
    // factory 
    a& new_a() 
    { 
     A* a = new A; 
     return *a; 
    } 
    A& a; 
}; 

然而當B的生命期結束時,B::a當然不會被銷燬,因爲它是一個參考。但B之外沒有訪問B::a。所以這是一個內存泄漏。爲了解決這個問題一個可以打電話從B::~B()

B::~B() {a.~A();} 

A::~A()但我已閱讀手動調用析構函數是一個沒有沒有,所以把以A::~A()來電的B::~B()析構函數放平,或不是嗎?

有更清潔的解決方案嗎?

+5

我認爲你需要重新考慮你的設計。例如,*爲什麼*你必須有一個參考?難道你沒有一個實際的實例(這是我推薦的)?還是一個指針(或者說是一個智能指針)? –

+0

'return * a;'引用指針。 '''a''''''''''''''''''''''''''''''''',''''A''的一個副本被捲起,但''''''A'被泄漏。 – user4581301

+0

@ user4581301沒有。 'new_a'返回一個引用(假設返回類型應該是'A&'不''a&')並且直接綁定到'B :: a'。沒有副本。 –

回答

4

delete &a;B的析構函數應該正確地做這項工作以避免內存泄漏。

我最好推薦工廠函數,而應該返回std::unique_ptr<A>。或者,您只需使用A的簡單實例作爲B的成員。

1

更清潔的解決方案是避免將指針轉換爲引用。數據成員參考A& a;意味着struct B不擁有a引用的對象。但是,就你的情況而言,它會造成混淆。

您應該更喜歡非擁有關係的引用(和原始指針),以及擁有關係的智能指針或值對象。

例如,std::unique_ptr<A> a;此處的數據成員將清楚地顯示所有權意圖,並且作爲獎勵,將在B銷燬時自動發佈。你甚至不需要在~B()析構函數中寫任何東西。

其結果是,你new a()功能可以這樣寫:

std::unique_ptr<A> new_a() { return {new A()}; }

其實你不需要寫new_a()。 C++標準庫已經爲你定義了一個這樣的函數:std::make_unique

+1

'unique_ptr'有一個顯式的構造函數,所以你需要做'return std :: unique_ptr {new A};'(或'return std :: make_unique ();',如你所說)。 –