操作符重载本身实现并不困难,例如
class A
{
friend ostream& operator<<(ostream& os,const class A& a);
{
os<<"value"<<a.value;
return os;
}
private:
int value;
};
但是如果A派生了新的类,为了能让同一个输出操作符自动识别继承自A类的对象并使用恰当的输出方式,则可以给基础类一个抽象的方法,派生类重写这个方法而达到针对不同的对象在运行时使用不同的输出格式.由于输出操作符不可以为抽象的,所以可以在不改变基类的这个公共接口的前提下另写一个实现输出的抽象成员方法print(),让输出操作符去调用这个方法.这样以来每派生一个类,则只需要修改其重写的print()方法即可.所以新的A类应该是
class A
{
friend ostream& operator<<(ostream& os,const class A& a)
{
a.print(os);
return os;
}
private:
int value;
virtual void print() const;
};
void A::print(ostream& os) const
{
os<<"value "<<value;
return os;
}
如果此时B类继承了A类,则B的输出操作符可以在不对A的设计进行任何更改的情况下简单的实现.
B类的部分应该是如下的样子
class B: public class A
{
friend ostream& operator<<(ostream& os,const class B& b)
{
b.print(os);
return os;
}
private:
int number;
void print(ostream& os) const;
};
void B::print(ostream& os) const
{
A::print(os);
os<<"number "<<number;
}
这里的类都比较小,可以容易的看出当A,B类的输出都不叫复杂的时候改动和更改都会比较方便.
思想方法来自<<C++沉思录>>