开发者

Operator << and inheritance

开发者 https://www.devze.com 2023-02-15 05:12 出处:网络
I have the following classes in C++: class Event { //... friend ofstream& operator<<(ofstream& ofs, Event& e);

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


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


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


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.


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());
0

精彩评论

暂无评论...
验证码 换一张
取 消