2015-04-17 82 views
0

我在寫一個涉及多態的C++程序。我需要重載運營商「< <」「>>」爲友元函數。 我有基類和3派生類:der1DER2der3和指向基礎類* p。如果我宣佈了功能朋友函數中基類參數類型的指針

istream &operator>>(istream &i,der1 &d1) {...} 
istream &operator>>(istream &i,der2 &d2) {...} 
istream &operator>>(istream &i,der3 &d3) {...} 

,並呼籲他們喜歡

base *p; 
p=new der1; 
cin>>p; 

程序無法編譯,因爲是用基地參數無功能。 但如果我宣佈它的話,它不會使任何區別,如果實際對象的類型爲der1DER2der3,但我希望它表現的不同取決於對象的類型。 我所能想到的只是在基礎中創建一個虛函數,並將其重載爲繼承類。但因此,我將不得不稱爲

*p>>cin 

這看起來並不那麼自然。 我該如何解決這個問題?

+0

那麼你聲明3個函數來引用,然後你使用一個指針調用一個函數;這將是一個不同的功能開始。是的,C++運行時無法查看您的基指針是否指向派生 - 多態性取決於「調用對象」,而不是參數對象。如果你說'p-> f()'* p中的代碼知道要調用什麼,但是在':: f(p)'中沒有內省* p並決定調用哪個f的代碼。該決定是在編譯時根據p的靜態標記進行的。 –

+0

您是否嘗試過'cin >>(* p)'?您正將一個指針傳遞給期望參考的操作員。 – user2891462

回答

2

您可以爲基類創建operator>>

istream &operator>>(istream &i, base *b) { 
    b->ReadFromIstream(i); 
    return i; 
} 

然後你讓ReadFromIstream虛擬函數,並從派生類中重載它。這種方式你有相同的語法cin >> p,他們根據p的類型行爲不同。

4

不要試圖使operator>>成爲會員。您不能也仍然保留cin在左側。只是使它成爲一個自由的功能,並有它調用成員(這樣可以是虛擬的):

struct base { virtual void read(istream &i); }; 

istream &operator>>(istream &i,base &b) {b.read(i); return i;} 
0

我認爲你有關於C++運行時能力的幻想:-)。 C++運行時不能(或者不選擇)查看你的基指針參數是否指向派生參數 - 多態性依賴於「調用對象」,而不是參數對象。如果您說p->f()*p中的代碼將知道要調用什麼,但在::f(p)中沒有代碼反映*p並決定調用哪個f。該決定是在編譯時根據p的靜態類型進行的。

也就是說,解決方法是由@DarkFalcon描述的策略。從函數調用對象的虛擬方法。