虚拟构造函数成语与智能指针 [英] virtual constructor idiom with smart pointers

查看:166
本文介绍了虚拟构造函数成语与智能指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多态类的层次结构,比如一个 Shape 抽象基类及其派生类。 Rectangle Circle 等等。 Virtual Constructor Idiom ,我想知道为什么我们需要在派生类中的虚拟构造函数的返回类型应该返回相同的类型使用智能指针时它的父类?

例如,请参见下面的代码,其中 clone() create )成员函数需要将 smart_pointers 返回到 Shape 类。但是,当使用简单指针时,返回类型可能与派生类的类型相同。

任何人都可以解释为什么我们需要以类似的方式处理这些函数?

I've a hierarchy of polymorphic classes, say a Shape abstract base class together with its derived classes, e.g. Rectangle, Circle, etc. Following the Virtual Constructor Idiom, I was wondering why we need that the return types of the virtual constructor functions in the derived classes should return the same type as in its parent class when using smart pointers?
For example, see the code below, where the clone() and create() member functions need to return smart_pointers to the Shape class. However, when using simple pointers, the return types can be of the same type as the one of the derived classes.
Could anybody explain why we need to handle those functions in the referred way?

class Shape;

typedef std::unique_ptr<Shape> shape_ptr;

class Shape{

    public:

        //typedef std::unique_ptr<Shape> 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> 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> 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;
};


推荐答案

当使用原始指针时,编译器允许协变返回类型,但是使用智能指针时是不可能的,因为 unique_ptr< Rectangle> 不源自 unique_ptr<形状> 。这两个类与编译器的观点完全无关。

When using raw pointers, the compiler allows for covariant return types but that's not possible when using smart pointers since unique_ptr< Rectangle > doesn't derive from unique_ptr< Shape >. The two classes are completely unrelated from the compiler's perspective.

这篇关于虚拟构造函数成语与智能指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆