Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert unique_ptr<Derived> to unique_ptr<Base>

A simple code

class Base {};
class Derived : Base {};

unique_ptr<Base> Create() {
    unique_ptr<Base> basePtr = make_unique<Derived>(); // compile error
    return basePtr;
}

produce a compile error ("no suitable conversion"). I found similar question where the solution is to use std::move. I tried this

unique_ptr<Derived> derived = make_unique<Derived>();
unique_ptr<Base> basePtr = std::move(derived); // compile error

but now std::move produces compile error. I also found question where (if I understood it well) the cast should be automatic if we use

unique_ptr<Base> basePtr = make_unique<Derived>(new Derived()); //compile error

but this is also not working (compile error), and it is also not recommended to use new with smart pointers.

What would be the proper solution?

The only working solution I found so far

unique_ptr<Base> basePtr = unique_ptr<Base>((Base*)new Derived());

looks really ugly.

like image 429
Dejan Avatar asked Dec 03 '22 11:12

Dejan


1 Answers

Your class is inheriting privately from the base class. This is the default for class, whereas the default for struct is public inheritance. This makes outside derived-to-base conversions invalid. unique_ptr handles derived-to-base conversions fine with public inheritance (live example):

 class Base {};
 class Derived : public Base {};
                 ^^^^^^

As noted below, it's also important to add a virtual destructor to the base class when using unique_ptr, as polymorphic destruction relies on this for well-defined behaviour. shared_ptr wouldn't require this, but that's getting off-topic.

like image 174
chris Avatar answered Dec 28 '22 12:12

chris