【问题标题】:Implementing operator<< for a derived class为派生类实现 operator<<
【发布时间】:2013-05-11 01:36:59
【问题描述】:

所以我有一个基类(Shape)和三个派生类,Circle、Rectangle 和 Square(Square 派生自 Rectangle)我正在尝试实现 operator

class Shape
{
     public:
     Shape(double w = 0, double h = 0, double r = 0)
     {
          width = w;
          height = h;
          radius = r;
     }

     virtual double area() = 0;
     virtual void display() = 0;

     protected:
     double width;
     double height;
     double radius;
};

ostream & operator<<(ostream & out, const Shape & s)
{
      s.display(out);
      return out;
}

class Rectangle : public Shape
{
     public:
     Rectangle(double w, double h) : Shape(w, h)
     {
     }

     virtual double area() { return width * height; }
     virtual void display() 
     {
        cout << "Width of rectangle: " << width << endl;
        cout << "Height of rectangle: " << height << endl;
        cout << "Area of rectangle: " << this->area() << endl;
     }
};

【问题讨论】:

  • 显然,display() 应该将ostream &amp; out 作为参数,写入out,而不是cout

标签: c++ class operators derived


【解决方案1】:

你像这样打电话给display

s.display( out );

但是display被定义为:

vritual void display() = 0;

函数的声明和定义不带参数。它应该引用std::ostream 作为参数:

virtual void display(std::ostream &) = 0;

它也应该是一个const 方法,因为您通过operator &lt;&lt; 重载传递const 对象:

virtual void display(std::ostream &) const = 0;

不要忘记,在display 的定义中,您应该写入ostream 对象,而不是具体的std::cout

这是Ideone上的编译程序。

【讨论】:

    【解决方案2】:

    这里有很多问题。首先,我们来处理打印问题:

    ostream & operator<<(ostream & out, const Shape & s)
    

    在这里,您传递的是const Shape。这意味着您只能在传入的s 上调用const 方法。但是,您没有将基类(或派生)中的任何方法标记为constareadisplay 都不应该改变对象的状态。其次,您尝试调用s.display(out),即将ostream&amp; 传递给display。您拥有的函数签名没有反映这一点。综上所述,我们得到:

     virtual double area() const = 0;
     virtual void display(ostream& out) const = 0;
    

    您还遇到了一些其他问题 - 一个未声明虚拟析构函数的基类。如果您打算多态地使用一个类,它必须有一个虚拟析构函数:

    virtual ~Shape() { }
    

    您还需要修改派生类中的方法:

     double area() const { return width * height; }
    
     void display(ostream& out) const
     {
        out << "Width of rectangle: " << width << endl;
        out << "Height of rectangle: " << height << endl;
        out << "Area of rectangle: " << area() << endl;
     }
    

    请注意,Rectangle 中的 display 总是事先打印到 cout

    【讨论】:

      【解决方案3】:

      您几乎是对的,这是可行的解决方案:

      #include <iostream>
      
      using std::cout;
      using std::endl;
      using std::ostream;
      
      class Shape
      {
           public:
           Shape(double w = 0, double h = 0, double r = 0)
           {
                width = w;
                height = h;
                radius = r;
           }
      
           virtual ~Shape() {} // Recommended!
      
           virtual double area() const = 0;
           virtual void display(ostream & out) const = 0;
      
           protected:
           double width;
           double height;
           double radius;
      };
      
      ostream & operator<<(ostream & out, const Shape & s)
      {
            // Since `s` is `const`, then `display` method should be `const` too.
            s.display(out);
            return out;
      }
      
      class Rectangle : public Shape
      {
           public:
           Rectangle(double w, double h) : Shape(w, h)
           {
           }
      
           virtual double area() const { return width * height; }
           virtual void display(ostream & out)  const
           {
              // Since `display` method is `const`, then `area` method should be
              // `const` too.
              out << "Width of rectangle: " << width << endl;
              out << "Height of rectangle: " << height << endl;
              out << "Area of rectangle: " << this->area() << endl;
           }
      };
      
      
      void main() {
          Rectangle r(1, 2);
      
          cout << r << endl;
      }
      

      请注意强制const-correctness类方法的const限定符。我添加了一些有用的 cmets,以便您可以顺利地遵循逻辑。根据经验,如果该方法不修改类成员,那么您应该将其声明为const

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-16
        • 2020-01-30
        • 1970-01-01
        • 2012-11-24
        • 1970-01-01
        相关资源
        最近更新 更多