运算符 <<和继承

发布于 2024-10-20 03:23:48 字数 578 浏览 1 评论 0 原文

我在 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; 

}

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

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

流年里的时光 2024-10-27 03:23:48

这是行不通的,因为这会调用基类的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!
}

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!
}
泪意 2024-10-27 03:23:48

尝试:

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

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";
        }
};
谷夏 2024-10-27 03:23:48

到目前为止的答案都有正确的想法,但在您继续执行并实现它之前,需要进行两个更改:

  • 使用 ostream 而不是 ofstream
  • 打印函数应该是 const。

因此:

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() 设为公共非虚拟函数,该函数调用受保护或私有虚拟函数,就像所有虚拟函数一样。

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.

懒的傷心 2024-10-27 03:23:48

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

在您尝试打印的类上调用显式打印方法。例如

vritual print(std::ofstream& os);

在基地和儿童中实施。

  • 或者 -

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

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

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());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文