Re: new Class(*this)
On Thursday, 9 April 2015 13:30:26 UTC+3, Chris Vine wrote:
On Wed, 8 Apr 2015 17:49:47 -0700 (PDT)
=D6=F6 Tiib <ootiib@hot.ee> wrote:
[snip]
No. There are covariance of raw pointers but there are no
covariance of smart pointers. So returning smart pointer
would lose virtual of clone method.
Can you unpack this one for me, with an example of what you have in
mind?
#include <memory>
struct A
{
// virtuals
virtual A*
clone() const { return new A(*this); };
virtual std::unique_ptr<A>
smart_clone() const { return std::unique_ptr<A>(new A(*this)); =
}
};
struct B : public A
{
// overrides
B*
clone() const override { return new B(*this); };
// OK
std::unique_ptr<B>
smart_clone() const override { return std::unique_ptr<B>(new B(=
*this)); }
// compile error
};
Raw pointers have covariance; smart pointers have no covariance in context =
of
virtual functions.
std::unique_ptr and std::shared_ptr have a templated version of the
move constructor and move assignment operator and (for std::shared_ptr)
copy constructor and copy assignment operator to allow implicit
covariant casts in the same circumstances that pointer casts would be
available.
It is not enough to affect the problem I described.
I have to return 'std::unique_ptr<A>' from 'smart_clone' of B or there are
no override. However that means the 'smart_clone' is less convenient than=
'clone' in situation where I need deep copy of 'std::unique_ptr<B>' and
so expect to have 'std::unique_ptr<B>' as well.
Contravariant casting using dynamic_cast is missing for smart pointers
(unless you do it by hand), but that is rarely what you want anyway.
I consider usage of 'dynamic_cast' only on the ultra rare cases when I need
cross casting. Otherwise I simply don't use it.