0

所以我有 A 类和 B 类,其中 B 类扩展了 A 类。我必须在两个类中重载 << 和 >>。我希望在 B 类的运算符的函数定义中,我可以从 A 类调用重载的运算符,但我在这样做时遇到了麻烦。

#include <iostream>
#include <string>
using namespace std;

class A {
friend ostream& operator<<(ostream& out, A a);
protected:
    int i;
    string st;
public:
    A(){
        i=50;
        st = "boop1";
    }
};

ostream& operator<<(ostream &out, A a) {
out << a.i << a.st;
return out;
}

class B : public A {
friend ostream& operator<<(ostream& out, B b);
private:
    int r;
public:
    B() : A() {
        r=12;
    }
};

ostream& operator<<(ostream &out, B b) {
out = A::operator<<(out, b);    //operator<< is not a member of A
out << "boop2" << b.r;
return out;
}

int main () {
B b;
cout << b;
}

我尝试在 B 的 operator<< 中调用 A 的 operator<<,但当然它实际上并不属于 A,因此无法编译。我应该如何实现这一目标?

另外,请注意,实际上 A 和 B 有自己的头文件和正文文件。

4

3 回答 3

3

您可以使您的B对象看起来像一个A对象:

std::ostream& operator<< (std::ostream& out, B const& b) {
    out << static_cast<A const&>(b);
    out << "boop2" << b.r;
    return out;
}

请注意,您几乎肯定不想传递要按值打印的对象。我已将签名更改为使用 a const&:这表明对象不会被更改,也不会被复制。

于 2012-09-21T00:06:34.467 回答
2

A'soperator<<确实不是的成员A,而是在命名空间范围内。这里正确的方法是使用类型强制来让重载解析做正确的事情。改变:

out = A::operator<<(out, b);

至:

out << static_cast<A>(b);

此外,您应该更改您的运算符以采用第二个参数 by const&,在这种情况下,它应该如下所示以避免额外的副本:

out << static_cast<A const&>(b);
于 2012-09-21T00:06:17.160 回答
0

它们是全局函数,不要使用范围解析运算符限定它们:

operator<<(out, static_cast<const A&>(b)) << "boop2" << b.r;

你必须强制转换它,这样你就不会调用你所在的函数并获得无限递归。另外,不要将结果分配operator<<out; 它不起作用,也不是你想做的。

此外,您的函数应该接受const A&'s 和const B&'s(也就是说,您应该通过const引用而不是值来接受参数)以防止不必要的复制。

于 2012-09-21T00:06:28.173 回答