我在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;事件。有没有办法避免这种行为?
谢谢
答案 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)
到目前为止,答案都是正确的想法,但在你开始实施之前,有两个变化:
因此:
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());