c++ - 重载 << 运算符和继承类

标签 c++ inheritance operators polymorphism

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

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

在我的类中,然后在类之后定义函数。我先验地认为将 virtual 添加到上述定义会使它起作用,但经过一番思考(以及我的编译器的错误)我意识到这没有多大意义。

我在一个测试用例上尝试了不同的策略,其中所有类成员都是公开的。例如:

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' 

所以在某种程度上这是“多态性变坏了”——基类运算符<<被调用而不是派生类运算符。在上面的示例中,如何为派生类调用正确的运算符?更一般地说,如果我的类有我想保护的私有(private)成员,我该如何在使用 friend 关键字时更正运算符重载?

最佳答案

您可以使用虚拟辅助函数。这是一个完全未经测试的示例,请原谅任何语法错误:

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 建议清理。

关于c++ - 重载 << 运算符和继承类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7690807/

相关文章:

c++ - 成功启用NaN移除方法上的-fno-finite-math-only

c++ - 在游戏中使用状态模式

c++ - 对原子变量的非原子操作,反之亦然

object - 是否可以在golang中同时指定带变量的结构和接口(interface)?

java - 无法调用类中的方法

Java:子类的构造函数具有父类的对象

f# - 无法在 F# 中扩展运算符?

c++ - 如何解除分配 llvm::module

php - PHP 中的 '&' 符号如何影响结果?

c++ 指向另一个类错误的指针 "no operator matches these operands."