2011-04-20 406 views
1

我有在衍生clases前的operatorr <<一個問題:運營商<<在派生類C++

如果我有

class Base 
{ 
     //...... 
     friend ostream& operator<<(ostream& out,Base &B) 
     { 
      return out<<B.x<<B.y<</*........*/<<endl; 
     } 
     //......  
}; 

是如下因素更多鈔票?

class Derived: public Base 
{ 
     //...... 
     friend ostream& operator<<(ostream& out,Derived &DERIVEDOBJECT) 
     { 
      return out<<DERIVEDOBJECT<<DERIVEDOBJECT.nonderivedvar1 <</*.....*/<< endl; 
     } 
} 

或把DERIVEDOBJECT<<運營商將不會導致<< recoqnizing它只是在基類的引用?

+1

@Aleksander - 使用每個代碼語句前4位或只使用'{}'這是本作的editior窗口代碼格式。 – Mahesh 2011-04-20 21:56:23

回答

10

你通常需要的是這樣的:

class Base { 

    virtual std::ostream &write(std::ostream &os) { 
     // write *this to stream 
     return os; 
    } 
}; 

std::ostream &operator<<(std::ostream &os, Base const &b) { 
    return b.write(os); 
} 

然後派生類中重寫write當/如果需要的話。

+0

+1:最後可能最好具有特定的寫入功能。 – 2011-04-20 21:59:21

+0

我認爲'b.write'不會調用虛函數,因爲它不是通過指針調用的。 – 2011-04-20 22:02:36

+1

@Giovanni:C++中的多態性與引用一樣好,與指針一樣。 – 2011-04-20 22:21:12

1

這將導致一個遞歸調用:

out<<DERIVEDOBJECT 

我會做:

friend ostream& operator(ostream& out,Derived &DERIVEDOBJECT) 
    { 
     return out << static_cast<Base&>(DERIVEDOBJECT) 
        << DERIVEDOBJECT.nonderivedvar1 
        <<.....<< endl; 
    } 

PS。空格和小寫字母是你的朋友。
按照慣例,所有大寫的標識符都是宏,因此您可能會通過對普通變量使用全部大寫標識符來混淆人。

+0

+1用於談論低級變量。那些傷害我的眼睛:-) – 2011-04-20 22:10:05

0

您可以通過向上轉型達到預期的結果爲基本類型:

struct base {}; 
std::ostream& operator<<(std::ostream& o, base const & b) { 
    return o << "base"; 
}; 
struct derived : base {}; 
std::ostream& operator<<(std::ostream& o, derived const & d) { 
    return o << static_cast<base&>(d) << " derived"; 
} 
int main() { 
    derived d; 
    std::cout << d << std::endl; // "base derived" 
}