重载流操作符时不能为虚函数
来源:互联网 发布: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.而上面说了,重载流操作符时不能为虚函数,如果不能是虚成员函数,有没有办法实现多态性呢?通过一些小技巧,还是可以实现的,即简单地让重载流操作符调用该类的另一个虚函数.下面是简单的代码实现
- #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;
- }
- 重载流操作符时不能为虚函数
- 重载流操作符时不能为虚函数
- 流运算符为什么不能重载为成员函数,只能用友元函数重载
- 流运算符为什么不能重载为成员函数,只能用友元函数重载
- 操作符重载为成员函数还是友元函数?
- 不能重载的操作符
- 函数操作符重载
- 运算符重载(重载为普通函数)
- 运算符重载(重载为成员函数)
- 有些运行符不能重载为友元函数,它们是:=,(),[]和->。
- 解析C++中不能重载为友元函数的四个运算符
- 解析C++中不能重载为友元函数的四个运算符
- WebService 类中构造函数不能重载为带参数
- 重载函数与重载操作符
- C++ 拷贝构造函数和重载赋值操作符不能相互调用
- 操作符重载函数多态性
- 重载函数调用操作符
- 重载函数调用操作符
- Shell编程总结
- epass1000 初始化 验证
- 养成思考和总结的习惯
- Java Web开发详解
- ITIL简介
- 重载流操作符时不能为虚函数
- 热点块竞争和解决
- [转贴]关于有盘无盘的结论,我自己亲自测试的
- shutdown和closesocket
- String类的C++实现
- system.dll,Nskhelper2.sys,oapejg.sys,991b0345.dat,NsPass0.sys等2
- Select列表下拉框之DIY
- 用 Tomcat 和 Eclipse 开发 Web 应用程序
- Ubuntu7.10 频繁读硬盘 trackerd tracker