运算符<<和继承

时间:2011-03-04 04:20:54

标签: c++ inheritance operators friend

我在C ++中有以下类:

class Event {
        //...
        friend ofstream& operator<<(ofstream& ofs, Event& e);

};


class SSHDFailureEvent: public Event {
    //...
    friend ofstream& operator<<(ofstream& ofs, SSHDFailureEvent& e);
};

我想要执行的代码是:

main(){

 Event *e = new SSHDFailureEvent();
 ofstream ofs("file");
 ofs << *e; 

}

这是一种简化,但我想要做的是将几种类型的事件写入文件 在一个文件中。但是,不是使用运算符&lt;&lt; SSHDFailureEvent,它使用运算符&lt;&lt;事件。有没有办法避免这种行为?

谢谢

4 个答案:

答案 0 :(得分:5)

那不行,因为它会为基类调用operator<<

您可以在基类中定义虚拟函数print并将其重新定义为所有派生类,并将operator<<仅定义为一次,

class Event {

      virtual ofstream& print(ofstream & ofs) = 0 ; //pure virtual  

      friend ofstream& operator<<(ofstream& ofs, Event& e);
};

//define only once - no definition for derived classes!
ofstream& operator<<(ofstream& ofs, Event& e)
{
   return e.print(ofs); //call the virtual function whose job is printing!
}

答案 1 :(得分:4)

尝试:

class Event
{
        //...
        friend ofstream& operator<<(ofstream& ofs, Event& e)
        {
            e.print(ofs);
            return ofs;
        }

        virtual void print(std::ofstream& ofs)
        {
             ofs << "Event\n";
        }

};


class SSHDFailureEvent: public Event
{
        virtual void print(std::ofstream& ofs)
        {
             ofs << "SSHDFailureEvent\n";
        }
};

答案 2 :(得分:1)

到目前为止,答案都是正确的想法,但在你开始实施之前,有两个变化:

  • 使用ostream not ofstream
  • 打印功能应为常量。

因此:

class Event
{
public:
    virtual ~Event();
    virtual std::ostream& printTo( std::ostream& ) const /*= 0*/;
   // other public methods
};

/*inline*/ std::ostream& operator<<(std::ostream& os, const Event& event)
{
    return event.printTo(os); 
}

只要print(或printTo)是公开的,就不需要让流操作符超载朋友。

您可以选择使用默认实现或将print方法设置为纯虚拟。

您还可以使print()公共非虚拟函数调用受保护或私有虚拟函数,就像所有虚函数一样。

答案 3 :(得分:0)

我在这里看到两种可能性:

在您要打印的类上调用显式打印方法。例如,实现

vritual print(std::ofstream& os);

在基地和孩子们。

  • 或 -

尝试动态地将基类强制转换为其子类。

SSHDFailureEvent* fe = dynamic_cast<SSHDFailureEvent*>(new Event());
相关问题