实现运算符<<对于派生类

时间:2013-05-11 01:36:59

标签: c++ class operators derived

所以我有一个基类(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;
     }
};

3 个答案:

答案 0 :(得分:0)

你这样叫display

s.display( out );

display定义为:

vritual void display() = 0;

声明并定义了没有参数的函数。它应该引用std::ostream作为参数:

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

当您通过const重载传入const对象时,它也应该是operator <<方法:

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

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

以下是Ideone上的编译程序。

答案 1 :(得分:0)

你几乎做对了,这是工作解决方案:

#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限定符。我添加了一些有用的注释,以便您可以顺利地遵循逻辑。根据经验,如果方法不修改类成员,那么声明它const

答案 2 :(得分:0)

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

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

在这里,你传递的是const Shape。这意味着您只能在传入的const上调用s方法。但是,您没有将基本(或派生)类中的任何方法标记为constareadisplay都不应该更改对象的状态。其次,您尝试拨打s.display(out),即将ostream&传递给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;
 }

请注意,display中的Rectangle始终预先打印到cout