標籤:
原文:http://blog.csdn.net/xhz1234/article/details/6510568
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++:建構函式和解構函式能否為虛函數