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

发布于 2024-12-09 03:08:35 字数 856 浏览 0 评论 0 原文

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

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' 

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

I've got a base class and then several derived classes. I would like to overload the "<<" operator for these derived classes. For normal operators, i.e. '+', virtual functions do the trick. What I understand to be the standard convention is to declare

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

within my class and then define the function after the class. A priori I would think adding virtual to the above definition would make it work, but after some thought (and errors from my compiler) I realize that doesn't make much sense.

I tried a different tack on a test case, where all the class members are public. For example:

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' 

So in some way this is "polymorphism gone bad" -- the base class operator<< is being called rather than the derived class operator. In the above example, how do I make the correct operator get called for the derived class? And more generally, if my class has private members I want to protect, how can I correct the operator overloading while using the friend keyword?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

自由范儿 2024-12-16 03:08:35

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

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

You can use a virtual helper function. Here's a completely untested example, so excuse any syntax mistakes:

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);
}

Edit: Cleaned up per @Omnifarious suggestions.

成熟的代价 2024-12-16 03:08:35

通常,您只需在基类中创建一个多态 print 方法,该方法由单个自由友元函数调用。

Usually you just create a polymorphic print method in the base class which is called by a single free friend function.

丑疤怪 2024-12-16 03:08:35

operator<< 设为一个自由函数,将调用转发给 Foo 类的 virtual 方法。

查看实际操作

Make operator<< a free function that forwards the call to a virtual method of class Foo.

See it in action.

未蓝澄海的烟 2024-12-16 03:08:35

通过适当的代码更正,您的代码可以正常工作;无需执行任何操作:

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'
}

演示。要访问私有成员,您可以将此函数设置为所需中的friend

With the proper code corrections in place, your code works fine; nothing to be done:

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. For accessing private members, you can make this function as friend in the desired class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文