如果我們沒有虛擬構造函數,那麼爲什麼我們有虛擬析構函數?構造函數也可以是虛擬的嗎?沒有虛擬構造函數但是虛擬析構函數
2
A
回答
16
- 在虛擬構造函數中沒有任何意義 - 您聲明瞭 類型的創建方式,它在編譯時是衆所周知的。編譯器 不需要[實際上不能,因爲動態調度基於 關於僅在創建對象之後創建的信息]。 所以沒有虛擬構造函數。
- 虛擬析構函數對於防止內存泄漏非常重要,並且 監視系統。假設你有
A* a = new B;
[B
從A
繼承 ],你後來delete a;
- 編譯器無法 知道a
的方式是B
[在一般情況下],並調用A
的 析構函數 - 如果它是不虛擬的,你可能會得到內存泄漏, 或其他故障。 - 使用虛擬析構函數 - 你確保
B
的析構函數被調用,因爲B
對象被銷燬。因爲在銷燬時需要
2
虛析構函數,你並不總是知道什麼類型的你正在處理:
Base *make_me_an_object()
{
if (the_moon_is_full())
return new Derived();
else
return new Base();
}
int main()
{
Base *p = make_me_an_object();
delete p;
}
中的delete
上述程序的main
不知道其是否p
指向Base
或Derived
對象,但如果Base
析構函數爲virtual
(應該是),則delete
可以使用*p
的vtable來查找正確的析構函數。
相比之下,在建造時,你總是知道你正在創建什麼樣的對象。 (而如果你不這樣做,那麼你可以創建一個工廠或「virtual constructor」,它知道。)
0
#include<iostream>
using namespace std;
class base {
protected:
int a;
};
class derived : public base {
};
int main() {
base * pointer_of_base = new derived;
delete pointer_of_base; // this will delete the base calss not the derived
}
的構造函數的調用上一次當我們創建類,所以當我們繼承的對象基類構造函數只調用一次,所以不需要虛擬。但是當我們從基類的指針訪問派生類時,如果我們想要刪除派生類的對象,我們通過基類的指針刪除它,但是刪除(pointer_of_base)將調用基類的析構函數但實際的座右銘是刪除派生類。因此我們需要析構函數在本質上是虛擬的。
相關問題
- 1. C++虛擬析構函數
- 2. CRT虛擬析構函數
- 3. 虛擬析構函數?
- 4. C++虛擬析構函數
- 5. 虛擬析構函數 - 有需要時
- 6. 虛擬構造函數問題
- 7. 虛擬方法和構造函數?
- 8. 虛擬複製構造函數
- 9. 沒有虛擬方法的虛擬析構函數有什麼危害嗎?
- 10. 虛擬析構函數如何工作?
- 11. 虛擬析構函數分段錯誤
- 12. 虛擬析構函數:不工作?
- 13. 有沒有用於使受保護的析構函數虛擬?
- 14. 如何檢測Delphi類是否具有虛擬構造函數?
- 15. 類有虛函數和可訪問的非虛擬析構函數
- 16. 從沒有虛擬析構函數的類繼承
- 17. 爲什麼STL容器沒有虛擬析構函數?
- 18. GNU編譯器警告「類具有虛擬函數但非虛擬析構函數」
- 19. 在虛擬析構函數中調用其他虛擬方法是否安全?
- 20. 從構造函數調用虛擬函數
- 21. GMock和模擬非虛擬方法的構造函數
- 22. 模擬一個虛擬拷貝構造函數
- 23. 從C++中的虛析構函數調用虛擬方法
- 24. 構造函數重構中的虛擬方法調用
- 25. 虛擬函數C++:虛擬函數已經有一個主體
- 26. 如果後代類沒有非靜態成員或析構函數,我是否需要虛擬析構函數?
- 27. 爲什麼我們有一個虛析構函數,而不是在C虛擬構造++?
- 28. 具有智能指針的虛擬構造函數成語
- 29. 在.NET中,一個類可以有虛擬構造函數嗎?
- 30. 受保護的構造函數與純虛析構函數
可能的重複[爲什麼我們在C++中沒有虛擬構造函數?](http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in- c) – 2012-03-29 10:58:42
@TomaszNurkiewicz:我認爲問題是,我們爲什麼在C++中有虛擬析構函數? – 2012-03-29 11:01:13