More effective C++入手快一年了,剛買的時候看過一遍,但由於水平太低,很多東西看不懂,這一個條款就是看不懂之一。最近又把這本書翻了出來,再好好啃啃吧。
看到標題的時候,將constructor虛化,首先感到很奇怪,構造函數怎么能是虛函數啊,在語義上構造函數是用來實例化一個對象的,是編譯時的狀態,如果構造函數是虛函數的話,在編譯的時候編譯器不知道該選用哪一個構造函數,它會傻眼的。帶着疑問,開始再來看這一章一遍,看看到底是如何將構造函數弄成虛函數的。
在這個章節中,作者舉了一些例子,用來說明virtual constructor。
例子1:
代碼如下:
class NLComponent { // 抽象基類,其中內含至少一個純虛函數 public: ... }; class TextBlock: public NLComponent{ // 沒有內含任何純虛函數 public: ... }; class Graphic: public NLComponent{ // 沒有內含任何純虛函數 public: ... }; class NewsLetter { // 一份實時通信是由一系列的NLComponent對象構成的 public: NewsLetter(istream& str);//NewsLetter擁有一個istream為自變量的構造函數,函數由stream讀取數據以便產生必要的核心數據結構 ... private: // 從str讀取下一個NLComponent的數據,產生組件,並返回一個指針指向它 static NLComponent* readComponent(istream &str); list<NLComponent *> components; }; NewsLetter::NewsLetter(istream &str) { while(str) { components.push_back(readComponent(str)); } }
由上面的代碼可以看出,NLComponent的Constructor並沒有虛擬化,他只是通過readComponent讀取istream產生不同類型的組件,返回組件的指針,之后將指針以基類指針(NLComponent*)類型存儲起來,用來在以后的調用可以實現多態,這樣就是Virtual Constructor。
例子2: virtual copy constructor
代碼:
class NLComponent{ public: // 聲明virtual copy constructor virtual NLComponent *clone() const = 0; };
class TextBlock:public NLComponent{ public: virtual TextBlock* clone() const { return new TextBlock(*this);} }; class Graphic:public NLComponent { public: virtual Graphic* clone() const {return new Graphic(*this);} };
NewsLetter{ public: NewsLetter(const NewsLetter& rhs);
private: list<NLComponent *> components; };
NewsLetter::NewsLetter(const NewsLetter& rhs) { for(list<NLComponent*>::const_iterator it = rhs.components.begin(); it != rhs.components.end(); ++it) { component.push_back((*it)->clone()); }
}
有上述代碼可以看出,通過clone這個虛函數,可以實現多態地拷貝NLComponent,即使NLComponent的拷貝構造函數是深拷貝還是淺拷貝都沒有關系,因為clone調用它的拷貝構造函數,並不是實現,這樣就可以屏蔽拷貝構造函數的實現細節。為以后的擴展做准備,挺好的。哈哈。
virtual copy constructor是利用"當派生類重新定義基類的虛函數時,不需要一定與基類的虛函數有相同的返回類型"。在基類中,clone返回一個指向base class的指針,而在派生類中,clone返回一個指向派生類的指針。這樣就可以實現virtual copy constuctor。
由於我的水平還不高,認識還有不足,請大家多多指點。謝謝。