繁体   English   中英

C ++ clone习语中协变返回类型的用处?

[英]Usefulness of covariant return types in C++ clone idiom?

通常的克隆习语使用协变返回类型:

struct Base {
    virtual Base* clone();
};

struct Derived : public Base {
    Derived* clone();
};

我已经读过这样的信息,即协变返回类型是C ++的后续添加,而较旧的编译器可能不支持它们。 在这种情况下, Derived类必须声明其clone成员函数以返回Base* 因为,大概我只是在使用这个习语时通过Base指针和/或引用来访问Derived对象,声明返回类型Derived*的真正用途/好处是什么?

另外,一个相关的问题:

我更喜欢使用智能指针来表达clone签名的所有权转移语义。 使用协变返回类型时,这是不可能的,因为auto_ptr<Derived>auto_ptr<Base>不协变。 (请注意,我不是在寻找关于智能指针使用的讲座 - 这里仅以auto_ptr为例)。 那么在这种情况下,有没有理由不让Derived返回auto_ptr<Base> 是否有更好的方式来表达所有权转移语义?

因为,据推测,我只是在使用这个成语时通过Base指针和/或引用来访问Derived对象...

你认为错了。 仅仅因为Base类存在并不意味着你将永远使用它。 如果我有一个带有子类CircleRectangleShape类,我也有一个Window类。 当我可以使用Rectangle时,我不打算使用Shape*作为窗口的位置和大小。

对于所有权转让,无论如何都不应该使用智能指针。 我知道你不想讲课,但我不是说智能指针很糟糕,你不应该在clone()使用它们。 您不能首先转让没有所有权的东西的所有权。 如果有人想要一个auto_ptr那么他们应该用克隆的原始指针构造它。 其他智能指针类型也是如此。

当你有一个指向Derived的指针并希望得到它的克隆时,它很有用:

Derived *ptr = ...;
Derived *clone = ptr->clone();

如果没有协变返回类型,您必须进行显式转换:

Derived *clone2 = (Derived*)ptr->clone();

请注意, Derived可能是更多派生类的基类,在这种情况下它更有意义。

不幸的是, auto_ptr<Derived>auto_ptr<Base>不协变。 因此,在这种情况下,您必须从所有克隆函数返回相同的类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM