Usefulness of covariant return types in C++ clone idiom?

妖精的绣舞 提交于 2019-12-10 16:40:28

问题


The usual clone idiom makes use of covariant return types:

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

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

I've read things to the effect that covariant return types were a later addition to C++, and older compilers may not support them. In this case the Derived class must declare its clone member function to return a Base*. Since, presumably, I'm only accessing Derived objects through Base pointers and/or references when using this idiom, what is the real use/benefit to declaring the return type Derived*?

Also, a related question:

I would prefer to use smart pointers to express transfer-of-ownership semantics for the clone signature. This is not possible when using covariant return types, as auto_ptr<Derived> is not covariant with auto_ptr<Base>. (Please note that I'm not looking for a lecture on the use of smart pointers -- auto_ptr is just used as an example here). So in this case, is there any reason not to have Derived return auto_ptr<Base>? Is there a better way to express the transfer-of-ownership semantics?


回答1:


It's useful when you have a pointer to Derived and want to get a clone of it:

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

without covariant return types you must do an explicit cast:

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

Note that Derived may be a base class for even more derived classes, in that case it makes even more sense.

Unfortunately auto_ptr<Derived> and auto_ptr<Base> are not covariant. So you must return the same type from all clone functions in that case.




回答2:


Since, presumably, I'm only accessing Derived objects through Base pointers and/or references when using this idiom...

You presume wrong. Just because a Base class exists doesn't mean you'll always be using it. If I have a Shape class with sub classes Circle and Rectangle, and I also have a Window class. I'm not going to use a Shape* for a the window's position and size when I can just use Rectangle.

For the transfer-of-ownership, you shouldn't be using smart pointers anyway. I know you don't want a lecture, but I'm not saying that smart pointers are bad, you just shouldn't be using them in clone(). You can't transfer ownership of something that has no ownership in the first place. If someone wants an auto_ptr then they should construct it with the cloned raw pointer. Same goes for other smart pointer types.



来源:https://stackoverflow.com/questions/4199556/usefulness-of-covariant-return-types-in-c-clone-idiom

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!