2017-06-01 54 views
-3
class A 
{ 
    public: 
     A(){ }; 
     ~A(){ }; 

     //stuff 
}; 

class B 
{ 
    public: 
     B(A* a){ pA = a;} 
     ~B(){ }; 

     A* pA; 
}; 

int main() 
{ 
    A instOfA = A(); 

    B instOfB = B(&instOfA); 

    return 0; 
} 

我不確定〜B()是否應該刪除它的指針數據成員* pA。即在descructor中重新分配指針

~B() 
{ 
    if(pA!=nullptr) delete pA; 
} 

我的猜測是需要刪除,因爲B在A * pA中分配它。

+1

你必須問自己的問題是:'B'擁有'B :: pA;'的對象指針嗎?在這種情況下,它指向'main()'中的'instOfA',它是一個局部變量。局部變量總是由它的範圍所有。你只是刪除了'new'分配的東西。 –

+1

_我的猜測是刪除是必要的,因爲B在A * pA._中分配它'''B''的構造函數在你的例子中沒有任何分配。 – nefas

回答

0

這是關於所有權,因此問題是一個設計問題。你不是動態地分配A,所以我不會讓B碰它。它將在主結束時被刪除。

,如果您分配的動態(A* instOfA = new A(); )的實例,那麼你可以,如果你想通過這個實例與B的所有權,並具有B-刪除它選擇。

我的猜測是需要刪除,因爲B在A * pA中分配它。

您的猜測是不正確的。 B沒有分配A.它所做的只是獲取主分配的實例的指針。

+0

這就是(其中一個原因)爲什麼你應該避免使用原始指針,而是使用引用和智能指針:它們對所有權更明確。 – nefas

0

你的猜測是不正確的,因爲

B instOfB = B(&instOfA); 

通過自動存儲時間的AB的構造函數的地址。操作員delete只能安全用於銷燬使用相應操作員new創建的對象。使用運算符delete銷燬未使用相應運算符new創建的對象時會導致未定義的行爲。

instOfA保證在main()返回時不再存在,因此不需要任何操作來銷燬它。任何導致它被銷燬兩次的行爲(所以它的析構函數在同一個對象上被調用兩次)也會導致未定義的行爲。

一般來說,設計您的班級B通常會更好,因此它會完全管理A(例如管理其使用期限)以確保一致性。通過接受一個指針,不可能防止(除了通過緊急文檔,並依靠程序員注意到文檔)傳遞給構造函數的對象不能正確處理析構函數。

如果您打算做delete pA,則沒有必要測試pA是否爲非NULL。該標準指定delete運算符對NULL指針沒有影響。