Convert unique_ptr<Derived> to unique_ptr<Base>

  • A+

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.


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.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: