重载流操作符时不能为虚函数

来源:互联网 发布:linux 查看文件夹大小 编辑:程序博客网 时间:2024/06/08 07:05

为了能够像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.而上面说了,重载流操作符时不能为虚函数,如果不能是虚成员函数,有没有办法实现多态性呢?通过一些小技巧,还是可以实现的,即简单地让重载流操作符调用该类的另一个虚函数.下面是简单的代码实现

  1. #include <iostream>
  2. using namespace std;
  3. class Base
  4. {
  5. private:
  6.     int x;
  7.     friend ostream& operator << (ostream& os, Base& theBase)
  8.     {
  9.         theBase.print(os);
  10.         return os;
  11.     }
  12. public:
  13.     Base() {}
  14.     Base(int a) : x(a) {}
  15.     virtual void print(ostream& os)
  16.     {
  17.         os << "Base.x = " << x;
  18.     }
  19. }; // end class Base definition
  20. class Derived : public Base
  21. {
  22. private:
  23.     int y;
  24. public:
  25.     Derived(int b) : y(b) {}
  26.     virtual void print(ostream& os)
  27.     {
  28.         os << "Derived.y = " << y;
  29.     }
  30. }; // end class Derived definition
  31. int main()
  32. {
  33.     Base* pb;
  34.     pb = new Base(10);
  35.     cout << *pb << endl;
  36.     delete pb;
  37.     pb = new Derived(20);
  38.     cout << *pb << endl;
  39.     delete pb;
  40.     
  41.     return 0;
  42. }


 

原创粉丝点击