2012-01-11 75 views
0

鑑於下面的代碼,爲什麼我會得到關於A的析構函數是私人的錯誤?顯然它是私有的,但我不明白爲什麼以這種方式初始化B的A對象實例會導致A的析構函數被調用。對象初始化期間的析構函數調用?

任何錯別字的道歉,我正在從非聯網系統的內存中重新創建代碼,並沒有編譯器。

class A 
{ 
    public: 
     A(int val) : x(val) {} 

    private: 
     int x; 
     ~A() {} 
}; 

class B 
{ 
    public: 
     B() : aInstance() {} 

    private: 
     A aInstance; 
}; 

int main() 
{ 
    B b; 
} 
+0

無法爲基於堆棧的對象(甚至是間接)執行此操作。有關私有析構函數的用法和限制的一個很好的討論在這裏:http://stackoverflow.com/questions/631783/what-is-the-use-具有析構函數作爲私有 – holtavolt 2012-01-11 18:11:41

回答

5

初始化本身使用析構函數不涉及,但B實例在main末被破壞。 B包含A,因此當B被銷燬時,A也必須銷燬 - 但A的dtor不可用,因此無法生成用於執行該操作的代碼。

2

由於B類包含A類的實例(如私有字段aInstance),它具有當B實例被破壞被破壞。

這正是您的main內發生的情況。由於B b;是在堆棧上分配和創建的,因此當函數結束並且必須銷燬時,它會超出範圍,就像C++中的每個本地對象一樣。

0

在main()的末尾,當B超出範圍時,B應該如何解除分配類型A的成員?

它不能,因爲你聲明瞭析構函數是私有的。

+0

它存在的問題不是B的主要問題,編譯器會自動創建需要刪除A的析構函數,它不能訪問析構函數。 – CashCow 2012-01-11 18:12:29

+0

修正了不清楚的先行詞。 – nsanders 2012-01-11 18:58:17

0

之所以這樣,是因爲AB的成員。類型B的默認生成構造函數必須是規則調用它的每個字段的析構函數。因此,有在這裏A析構函數隱式調用到它無法訪問,你會得到錯誤

0

我懷疑從構造函數中調用A的析構函數。當b在主程序超出範圍時(程序終止時),A的析構函數可能被調用。

0

它實際上是需要訪問析構函數而不是main()的B.

如果你讓B成爲A的朋友,它會工作。如果你將main()作爲A的朋友,它不會編譯。因爲A的實例被聲明爲「自動」,即它是一個類成員,所以它的刪除不會發生在B的析構函數中,但會在B的銷燬過程中發生。然而,這被認爲是在B作爲一個類的訪問範圍。

相關問題