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());
精彩评论