[英]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类存在并不意味着你将永远使用它。 如果我有一个带有子类Circle
和Rectangle
的Shape
类,我也有一个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.