我正在编写一个涉及多态的C ++程序。我需要将运营商 “<<” 和 “>>” 重载为朋友功能。 我有基类 base 和3个派生类: der1 , der2 , der3 以及指向基类 * p 的指针。如果我将函数声明为
istream &operator>>(istream &i,der1 &d1) {...}
istream &operator>>(istream &i,der2 &d2) {...}
istream &operator>>(istream &i,der3 &d3) {...}
并将其称为
base *p;
p=new der1;
cin>>p;
程序无法编译,因为没有 base 参数的功能。 但是,如果我这样声明,如果实际对象的类型为 der1 , der2 或 der3 ,虽然我希望它的行为会有所不同,具体取决于对象的类型。 我能想到的只是在base中创建一个虚函数并将其覆盖为继承的类。但是,我必须将这些函数称为
*p>>cin
看起来不那么自然。 我该如何解决这个问题呢?
答案 0 :(得分:4)
不要试图让operator>>
成为会员。您无法在左侧保留cin
。只需使它成为一个自由函数并让它调用一个成员(然后可以是虚拟的):
struct base { virtual void read(istream &i); };
istream &operator>>(istream &i,base &b) {b.read(i); return i;}
答案 1 :(得分:2)
您可以为基类创建operator>>
:
istream &operator>>(istream &i, base *b) {
b->ReadFromIstream(i);
return i;
}
然后将ReadFromIstream
作为虚函数,并从派生类中重载它。这样,您使用相同的语法cin >> p
,并且根据p
的类型,它们的行为会有所不同。
答案 2 :(得分:0)
我认为你有关于C ++运行时能力的幻想:-)。 C ++运行时不能(或选择不)查看你的基指针参数是否指向派生的 - 多态性取决于“调用对象”,而不是参数对象。如果您说p->f()
,*p
中的代码会知道要拨打什么电话,但在::f(p)
中,没有代码可以内省*p
并决定调用哪个f
。该决定是在编译时根据p
的静态类型做出的。
也就是说,解决方法是@DarkFalcon描述的策略。从函数中调用对象的虚方法。