C++:构造函数和析构函数能否为虚函数
C++:構造函數和析構函數能否為虛函數?
簡單回答是:構造函數不能為虛函數,而析構函數可以且常常是虛函數。
(1) 構造函數不能為虛函數
讓我們來看看大牛C++之父 Bjarne Stroustrup 在《The C++ Programming Language》里是怎么說的:
To construct an object, a constructor needs the exact type of the object it is to create. Consequently,?a constructor cannot be virtual. Furthermore, a constructor is not quite an ordinary function, In particular, it interacts with memory management in ways ordinary member functions don't. Consequently, you cannot have a ponter to a constructor.
---?From?《The C++ Progamming Language》15.6.2
然而大牛就是大牛,這段話對一般人來說太難理解了。那下面就試著解釋一下為什么:
這就要涉及到C++對象的構造問題了,C++對象在三個地方構建:(1)函數堆棧;(2)自由存儲區,或稱之為堆;(3)靜態存儲區。無論在那里構建,其過程都是兩步:首先,分配一塊內存;其次,調用構造函數。好,問題來了,如果構造函數是虛函數,那么就需要通過vtable?來調用,但此時面對一塊 raw memeory,到哪里去找?vtable?呢?畢竟,vtable?是在構造函數中才初始化的啊,而不是在其之前。因此構造函數不能為虛函數。
?
(2)析構函數可以是虛函數,且常常如此
這個就好理解了,因為此時 vtable 已經初始化了;況且我們通常通過基類的指針來銷毀對象,如果析構函數不為虛的話,就不能正確識別對象類型,從而不能正確銷毀對象。
?
?
困惑我們的是我們卻經常看到“虛構造函數”這樣的說法,這就要歸咎于不負責任或者說誤人子弟的媒體了(包括書、技術文章等等)。因為他們說的是類似下面這樣的做法:
class Expr {
public:
???? Expr();
???? Expr(const Expr&);
???? virtual Expr* new_expr() { return new Expr(); }
???? virtual Expr* clone() { return new Expr(*this); }
};
---轉自Linux Tour
總結
以上是生活随笔為你收集整理的C++:构造函数和析构函数能否为虚函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Arrays 工具类
- 下一篇: c# MEF框架(三 导出类的方法和属性