【C++ techniques】虚化构造函数、虚化非成员函数

constructor的虚化

  • virtual function:完成“因类型而异”的行为;
  • constructor:明确类型时构造函数;
  • virtual constructor:视其获得的输入,可产生不同的类型对象。
//假如写一个软件,用来处理时事新闻,其内容由文字和图形构成

class NTComponent{   //抽象基类,用于时事消息的组件
public:				 //其中至少含有一个纯虚函数
	...
};
 
class TextBlock:public NTComponent{
public:
	...				//没有内含有任何纯虚函数
};	
 
class Graphic : public NTComponent{
public:
	...				//没有内含有任何纯虚函数
};		

class NewsLetter{	//一份时事通讯是有一系列的NTComponent对象构成
public:
	...
private:
	list<NTComponent*> components;
};	
//NewsLetter对象尚未开始运作的时候,可能存储于磁盘中
//让NewsLetter拥有一个constructor并用istream作为自变量
//这个constructor将从stream读取数据以便产生必要的核心数据结构:

class NewsLetter{
public:
	NewsLetter(istream& str);
	...
};
 
NewsLetter::NewsLetter(istream& str)
{
	while(str)
	{
		read the next component object;
		add the object to the list of 
		this newsletter's components;
	}
}
//如果将棘手的东西搬移到另一个名为readComponent的函数:

class NewsLetter{
public:
	...
private:
	static NTComponent* readComponent(istream& str);
	...                                             
};
 
NewsLetter::NewsLetter(istream& str)
{
	while(str)
	{
		//将readComponent返回的指针加到component list尾端,
		//“push_back”是一个list member function,用来将对象安插
		//到list尾端
		components.push_back(readComponent(str));
	}
}

此时readComponent产生新对象,所以行为仿若constructor,但是它能够产生不同类型的对象,所以我们称之它为一个virtual constructor

virtual constructor:

  • 某种函数,视其获得的输入,可产生不同的类型对象;
  • 在许多情况下有用,比如从磁盘(或网盘或磁带等)读取对象信息。

virtual copy constructor:

  • 返回一个指针,指向其调用者(某对象)的一个新副本;
  • 基于这种行为,virtual copy constructors通常以copySelf或cloneSelf命名,或者像下面一样命令为clone。
class NLComponent{
public:
	//声明 virtual copy constructor
	virtual NLComponent* clone() const = 0;
	...
};
 
class TextBlock:public NLComponent{
public:
	virtual TextBlock* clone() const //virtual copy constructor
	{
		return new TextBlock(*this);
	}
	...
};
 
class Graphic:public NLComponent{
public:
	virtual Graphic* clone() const //virtual copy constructor
	{
		return new Graphic(*this);
	}
	...
};
class NewsLetter{
public:
	NewsLetter(const NewsLetter& rhs);
	...
private:
	list<NLComponent*> components;
};
 
NewsLetter::NewsLetter(const NewsLetter& rhs)
{
	//迭代遍历rhs list,运用每个元素的virtual copy constructor,
	//将元素复制到对象的component list中。
	for(list<NLComponent*>::const_iterator it = rhs.components.begin();
			it != rhs.components.end(),++it)
			{
				components.push_back((*it)->clone());
			}
}

non-member functions的虚化

写一个虚函数做实际工作,再写一个什么都不做的非虚函数,只负责调用虚函数;为了避免此巧妙安排蒙受函数调用所带来的成本,也可以将非虚函数inline化。

//为TextBlock和Graphic实现出output操作符

class NLComponent{
public:
	virtual ostream& print(ostream& str) const = 0;
};
 
class TextBlock:public NLComponent{
public:
	virtual ostream& print(ostream& str);
};
 
class Graphic:public NLComponent{
public:
	virtual ostream& print(ostream& str);
};
 
inline ostream& operator<<(ostream& s,const NLComponent& c)
{
	return c.print(s);
}

你可能感兴趣的:(C++进阶,c++,开发语言,笔记)