【问题标题】:Operator << and inheritance运算符 << 和继承
【发布时间】:2011-07-08 13:23:59
【问题描述】:

我在 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 的运算符

谢谢

【问题讨论】:

    标签: c++ inheritance operators friend


    【解决方案1】:

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

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

    vritual print(std::ofstream& os);
    

    在基地和孩子。

    • 或者-

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

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

    【讨论】:

    • 使用 static_cast 当且仅当绝对确定指向的对象也是派生类型。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      这是行不通的,因为它会为基类调用operator&lt;&lt;。

      您可以在基类中定义一个虚函数print,然后将其重新定义为所有派生类,并且只定义一次operator&lt;&lt;,

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

      【讨论】:

        【解决方案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";
                }
        };
        

        【讨论】:

          猜你喜欢
          • 2023-04-02
          • 1970-01-01
          • 2011-12-05
          • 2015-06-27
          • 2010-10-14
          • 2021-06-07
          • 2012-04-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多