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。
由于我的水平还不高,认识还有不足,请大家多多指点。谢谢。