2012-09-21 155 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),以防止不必要的複製。