идиома виртуального конструктора с интеллектуальными указателями

У меня иерархия полиморфных классов, скажем, абстрактный базовый класс 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;
};

6
задан Tin 15 January 2012 в 14:37
поделиться