2011-04-20 569 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" 
}