重载<<运算符和继承的类

时间:2011-10-07 17:33:51

标签: c++ inheritance operators polymorphism

我有一个基类,然后有几个派生类。我想重载“<<”这些派生类的运算符。对于普通算子,即'+',虚函数可以解决问题。我理解的标准惯例是声明

friend ostream& operator<<(ostream& out, MyClass& A);

在我的课程中,然后在课程后定义函数。先验我认为将虚拟添加到上面的定义会使它工作,但经过一些思考(和编译器的错误)我意识到这没有多大意义。

我在测试用例上尝试了不同的方法,所有的类成员都是公开的。例如:

class Foo{
 //bla
};

ostream& operator<<(ostream& out, Foo& foo){
  cout << "Foo" << endl;
  return foo;
}

class Bar : public Foo{
 //bla
};

ostream& operator<<(ostream& out, Bar& bar){
  cout << "Bar" << endl;
  return bar;
}

///////////////////////

Bar bar = Bar();
cout << bar << endl; // outputs 'Foo', not 'Bar' 

因此,在某种程度上,这是“多态性变坏” - 基类运算符&lt;&lt;被调用而不是派生类操作符。在上面的例子中,如何为派生类调用正确的运算符?更一般地说,如果我的班级有我想要保护的私人成员,我怎样才能在使用friend关键字时纠正运算符重载?

4 个答案:

答案 0 :(得分:6)

您可以使用虚拟助手功能。这是一个完全未经测试的例子,所以请原谅任何语法错误:

virtual ostream& Foo::print(ostream& out) const {
    return out << "Foo";
}

virtual ostream& Bar::print(ostream& out) const {
    return out << "Bar";
}

// If print is public, this doesn't need to be a friend.
ostream& operator<<(ostream& out, const Foo& foo) {
    return foo.print(out);
}

修改:根据@Omnifarious建议清理。

答案 1 :(得分:2)

通常,您只需在基类中创建一个多态print方法,该方法由一个免费的朋友函数调用。

答案 2 :(得分:1)

operator<<设为免费功能,将调用转发给virtual类的Foo方法。

<强> See it in action

答案 3 :(得分:1)

通过适当的代码更正,您的代码可以正常工作;没有什么可做的

ostream& operator<<(ostream& out, Foo& foo) {
  out << "Foo" << endl;  // 'out' and not 'cout'
  return out;  // returns 'out' and not 'foo'
}

ostream& operator<<(ostream& out, Bar& bar) {
  out << "Bar" << endl;  // 'out' and not 'cout'
  return out;  // returns 'out' and not 'bar'
}

Demo。要访问private成员,您可以在所需的friend中将此功能设为class