为了能够像cout,cin这样使用<<,>>流操作符来操作对象,对<<,>>的重载有下面几个约定:第一个参数为ostream或istream的引用,第二个参数为类类型,返回与第一个参数类型相同的引用.所以,可以基本得到重载流操作符的原型:
ostream& operator << (ostream& os, ClassType& ct);
istream& operator >> (istream& is, ClassType& ct);
现在来说说标题所指,重载流操作符时不能为虚函数.为什么呢,因为重载流操作符不应该是类的成员函数,而应该把它们声明为友元,既然不能是成员函数,自然就不能是虚函数.都知道C++的每个类的对象都包含有一个隐藏的this指针,指向对象本身,假设把重载流操作符的函数声明为类的成员函数,如下:
class Demo
{
public:
ostream& operator << (ostream& os);
istream& operator >> (istream& is);
};
在调用的时候编译器会把上面的函数理解成
ostream& operator << (this, ostream& os);
istream& operator >> (Demo*, istream& is); //与this等同
很明显这与我们上面所说的约定不同.
现设计两个类,其中class Derived : public Base.我们希望能够像使用简单数据类型那样输出对象,cout << aBase << aDerived.而上面说了,重载流操作符时不能为虚函数,如果不能是虚成员函数,有没有办法实现多态性呢?通过一些小技巧,还是可以实现的,即简单地让重载流操作符调用该类的另一个虚函数.下面是简单的代码实现
- #include <iostream>
- using namespace std;
- class Base
- {
- private:
- int x;
- friend ostream& operator << (ostream& os, Base& theBase)
- {
- theBase.print(os);
- return os;
- }
- public:
- Base() {}
- Base(int a) : x(a) {}
- virtual void print(ostream& os)
- {
- os << "Base.x = " << x;
- }
- }; // end class Base definition
- class Derived : public Base
- {
- private:
- int y;
- public:
- Derived(int b) : y(b) {}
- virtual void print(ostream& os)
- {
- os << "Derived.y = " << y;
- }
- }; // end class Derived definition
- int main()
- {
- Base* pb;
- pb = new Base(10);
- cout << *pb << endl;
- delete pb;
- pb = new Derived(20);
- cout << *pb << endl;
- delete pb;
- return 0;
- }