Operator << and inheritance

≡放荡痞女 提交于 2021-02-08 05:01:55

问题


I have the following classes in C++:

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

};


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

The code I want to execute is:

main() {

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

}

This is a simplification, but what I want to do is write into a file several type of Events in a file. However, instead of using the operator << of SSHDFailureEvent, it uses the operator << of Event. Is there any way to avoid this behavior?

Thanks


回答1:


That would not work, as that would call operator<< for the base class.

You can define a virtual function print in base class and re-define it all derived class, and define operator<< only once as,

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!
}



回答2:


Try:

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";
        }
};



回答3:


The answers so far have the right idea but before you run ahead and implement it, two changes:

  • Use ostream not ofstream
  • The print function should be const.

Thus:

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); 
}

As long as print (or printTo) is public there is no need to make the stream operator overload a friend.

You have the option of having a default implementation or making the print method pure virtual.

You can also make print() a public non-virtual function that calls a protected or private virtual one, as is the case with all virtual functions.




回答4:


I see two possibilities here:

Call an explicit print method on the class you are trying to print. For example implement

vritual print(std::ofstream& os);

in the base and the children.

  • Or -

Attempt to dynamically cast the base class to it's children.

SSHDFailureEvent* fe = dynamic_cast<SSHDFailureEvent*>(new Event());


来源:https://stackoverflow.com/questions/5189614/operator-and-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!