2012-07-20 65 views
0

我有2個類,基類是「端口」,派生類是「VintagePort」。 據我所知如果我使用引用或基類指針派生類的對象,它會自動找到正確的方法,而不是引用或指針,但完全對象(如果方法是虛擬的)。C++:朋友函數,派生類

在我的情況下,你可以看到兩個班級都有朋友功能「操作員< <」。但它看起來像當我使用基類的指針時,它只從基類調用函數。如果我使用「cout < < VintagePort」它工作正常。 我的問題:它工作正常,或者我應該修復代碼中的東西?

std::ostream& operator<<(std::ostream& os, const Port& p) 
{ 
os << p.brand << ", " << p.style << ", " << p.bottles << endl; 
return os; 
} 

std::ostream& operator<<(std::ostream& os, const VintagePort& vp) 
{ 
os << (const Port &) vp; 
cout << ", " << vp.nickname << ", " << vp.year << endl; 
return os; 
} 




VintagePort vp1; 
VintagePort vp2("Gallo", "lekko brazowy", 50, "Blaze", 1990); 
VintagePort vp3(vp2); 

Port* arr[3]; 
arr[0] = &vp1; 
arr[1] = &vp2; 
arr[2] = &vp3; 

for (int i = 0; i < 3; i++) 
{ 
    cout << ">>>>> " << i+1 << " <<<<<" << endl; 
    cout << *arr[i]; // call for base class instead derived class 
    arr[i]->Show();  
} 
+0

我覺得程序工作正常這是執行功能'的std :: ostream的和運營商<<(STD :: ostream&os,const Port&p)' 因爲你傳遞的參數確實是一個指向'Port'的指針,而不是'VintagePort',所以它調用函數匹配參數列表。在這個例子中繼承並不重要,因爲<<運算符的重載,即使是朋友,也不是該類的成員。 – jlledom 2012-07-20 11:50:12

回答

5

編譯器現在不會將指針實際指向繼承類。解決此問題的一種方法是在基類中爲輸出提供虛函數,並在繼承基類的類中覆蓋它。然後在輸出操作符中調用這個虛擬方法。

0

在C++中,多態只能通過虛函數實現,並且operator<<不是一個(因爲第一個參數是std::ostream,所以不能用於你的目的)如果你需要這種行爲,簡單的方法是提供層次結構中的虛擬打印功能,並具備operator<<轉發調用執行動態調度。

struct base { // Don't forget virtual destructors 
    virtual void print(std::ostream&) const; 
}; 
struct derived : base { 
    virtual void print(std::ostream&) const; 
}; 
std::ostream& operator<<(std::ostream& o, const base& b) { 
    b.print(o); 
    return o; 
}