2012-09-21 66 views
0

所以我有A类和B类,其中B类扩展了A类。我必须在两个类中超载<和<。我希望在B类运算符的函数定义中,我可以调用A类的重载运算符,但是我很难这样做。继承C++中的朋友操作符

#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版的操作< <的,当然它实际上并不属于A,所以不能编译。我应该如何实现这一目标?

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

+0

你有没有考虑让操作符重载A的成员? – Borgleader

+1

@Borgleader:你不能让operator <<成为A的成员,因为A出现在操作符的右侧,而不是左侧。它必须是独立功能或朋友功能。 – bstamour

+0

@SethCarnegie:由于答案得到解决,我删除了我的评论(我知道这是错的;) –

回答

3

你可以让你B物体看起来像一个A对象:

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

注意,你几乎肯定不希望传递对象按值打印。我改变了签名来代替使用const&:这表示对象不会被更改,也不会被复制。

+0

欢呼,现在完美! – thorium220

+0

我应该在几个小时前问过这个问题,但是......我如何对操作员>>做同样的事情? – thorium220

+0

那么,对于你想要使用非const引用的输入,也就是说,投射将是'static_cast (b)'。 –

2

Aoperator<<确实A一员,而是在命名空间范围。这里的正确方法是使用类型强制让重载解决方案做正确的事情。变化:

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

到:

out << static_cast<A>(b); 

此外,你应该改变你的运营商通过const&采取第二个参数,在这种情况下,它应该是为了避免额外的复制如下:

out << static_cast<A const&>(b); 
0

他们是全球性的功能,不与范围分辨率运营商限定它们:

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

你必须施放它,所以你不要调用你所在的函数并获得无限递归。另外,请不要将operator<<的结果分配给out;它不会工作,这不是你想要做的。

而且你的职责应该接受const A&的和const B&的(也就是说,你应该const参考,并不值接受paramters),以防止不必要的复制。