class A {
public:
A() { }
~A() { cout << "A Destructor \n" ; }
};
class B :public A{
public:
B() { }
virtual ~B() { cout << "B Destructor \n" ; }
};
class C : public B {
public:
C() { }
~C() { cout << "C Destructor \n"; }
};
int main()
{
A *pointA = new A;
A *pointB = new B;
A *pointC = new C;
delete pointA;
delete pointB;
delete pointC;
}
-1
A
回答
10
它會在第二次(和第三次)刪除時調用未定義的行爲,因爲A的析構函數不是虛擬的。
§5.3.5/ 3:
如果靜態類型的操作數是從它的動態類型不同,則 靜態類型應爲基類操作數的動態型的和靜態型應有一個虛擬析構函數或行爲未定義。
如果你犯了一個虛擬的析構函數,你得到良好定義的行爲,並動態類型的析構函數被調用。 (以及每個那些反過來的調用基析構函數)。您的輸出將是:
析構函數
乙析
析構函數
Ç析
乙析
析構函數
什麼是值得的,當你接近一個可編譯的片段時,你應該離開t他包括。此外,只需使用struct
而不是class
來簡化public
的內容,並省略空的構造函數。
+0
非常感謝Gman。 – user373215 2010-06-24 12:15:23
0
正如GMan指出的,試圖在基指針上調用delete操作符需要虛擬析構函數來讓編譯器能夠正確銷燬子類對象。很多人把這個過分簡化爲一條規則,比如「如果一個類有虛函數,它需要一個虛擬析構函數。」情況並非一定如此;即使沒有虛函數的基類仍然需要虛析構函數,如果你想允許客戶端通過基指針來刪除類。如果你不這樣做,析構函數應該受到保護,而不是公開的。
有一本很好的書,詳細描述了這一點,更多的稱爲Herb Sutter的C++編碼標準。我推薦它作爲C++冒險的起點。 :-)
相關問題
- 1. 下面的代碼是做什麼的?
- 2. 下面的代碼是做什麼的?
- 3. 下面的代碼是做什麼的?
- 4. 下面這段代碼做什麼
- 5. 給我下面的代碼應該寫什麼測試?
- 6. 代碼中有什麼問題時,我應該做什麼?
- 7. 代碼說明
- 8. 代碼說明
- 9. XMLHttpRequest在該代碼中做了什麼
- 10. 以下代碼行在下面的ruby代碼中做了什麼?
- 11. 以下javascript代碼的說明
- 12. 應用程序做對面的複選框應該做什麼
- 13. 我應該在C++中爲C中的代碼做些什麼?
- 14. 下面的代碼行是做什麼的?
- 15. 在下面的代碼中,word ='word'和words = []是做什麼的?
- 16. 下面的代碼中的邏輯或做什麼
- 17. PHP preg_replace:下面的代碼是做什麼的?
- 18. 下面的Java代碼是做什麼的
- 19. 下面的mod_rewrite代碼是做什麼的?
- 20. 帶SVN的DokuWiki:如何以及在源代碼控制下應該做什麼
- 21. 請在下面的代碼中說明執行的順序
- 22. 你有什麼聰明的算法比下面的代碼
- 23. 下面提到的代碼在.htaccess中做了什麼?
- 24. $符號在下面的代碼中做了什麼?
- 25. 有沒有人知道下面的代碼可能做什麼?
- 26. 在下面的代碼末尾做什麼()?
- 27. 在下面的代碼中,%做了什麼?
- 28. 「this」在下面的代碼中做了什麼
- 29. 有人可以請解釋下面的代碼做什麼?
- 30. 什麼以下C代碼片做
這是功課嗎? – Patrick 2010-06-24 10:36:44
必須與帕特里克一致,聞起來像功課。 – Puppy 2010-06-24 10:45:35
這不是作業。我試圖理解,爲什麼會拋出未定義的行爲? – user373215 2010-06-24 10:49:10