У меня иерархия полиморфных классов, скажем, абстрактный базовый класс Shape
вместе с его производными классами, например Rectangle
, Circle
и т. Д. Следуя идиоме виртуального конструктора , мне было интересно, зачем нам нужно, чтобы возвращаемые типы функций виртуального конструктора в производных классах при использовании интеллектуальных указателей вернуть тот же тип, что и в родительском классе?
Например, в приведенном ниже коде функции-члены clone ()
и create ()
должны возвращать smart_pointers
в Shape
класс. Однако при использовании простых указателей
возвращаемые типы могут быть того же типа, что и один из производных классов.
Может ли кто-нибудь объяснить, почему нам нужно обрабатывать эти функции указанным способом?
class Shape;
typedef std::unique_ptr shape_ptr;
class Shape{
public:
//typedef std::unique_ptr shape_ptr;
Shape(){};
virtual ~Shape(){};
virtual void draw() const = 0;
virtual float area() const = 0;
virtual shape_ptr clone() const = 0;
virtual shape_ptr create() const = 0;
//virtual Shape*clone() const = 0;
//virtual Shape*create() const = 0;
};
class Rectangle:public Shape{
public:
typedef std::unique_ptr rectangle_SmartPtr;
Rectangle(int height=0, int width=0):m_Height(height),m_Width(width){};
Rectangle(const Rectangle & rect):m_Height(rect.m_Height),m_Width(rect.m_Width){};
~Rectangle(){};
virtual void draw() const;
virtual float area() const;
//virtual rectangle_SmartPtr clone() const{ return rectangle_SmartPtr(new Rectangle(*this)); };
// error C2555: 'Rectangle::clone': overriding virtual function return type differs and is not covariant from 'Shape::clone'
//virtual rectangle_SmartPtr create() const{ return rectangle_SmartPtr(new Rectangle()); };
// error C2555: 'Rectangle::create': overriding virtual function return type differs and is not covariant from 'Shape::create'
virtual shape_ptr clone() const{ return shape_ptr(new Rectangle(*this)); }; //OK
virtual shape_ptr create() const{ return shape_ptr(new Rectangle()); }; //OK
//virtual Rectangle* clone() const{ return new Rectangle(*this); }; //OK
//virtual Rectangle* create() const{ return new Rectangle(); }; //OK
private:
int m_Height;
int m_Width;
};
class Circle:public Shape{
public:
typedef std::unique_ptr circle_SmartPtr;
Circle(float radius=0):m_Radius(radius){};
Circle(const Circle & other):m_Radius(other.m_Radius){};
~Circle(){std::cout << "Circle destructor: " << this << std::endl; };
virtual void draw() const;
virtual float area() const;
//virtual circle_SmartPtr clone() const{ return circle_SmartPtr(new Circle(*this)); };
// error C2555: 'Circle::clone': overriding virtual function return type differs and is not covariant from 'Shape::clone'
//virtual circle_SmartPtr create() const{ return circle_SmartPtr(new Circle()); };
// error C2555: 'Circle::create': overriding virtual function return type differs and is not covariant from 'Shape::create'
virtual shape_ptr clone() const{ return shape_ptr(new Circle(*this)); }; //OK
virtual shape_ptr create() const{ return shape_ptr(new Circle()); }; //OK
//virtual Circle* clone() const{ return new Circle(*this); }; //OK
//virtual Circle* create() const{ return new Circle(); }; //OK
private:
float m_Radius;
};