C++:構造函數和析構函數能否為虛函數


原文: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM