9

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.

Dejan
  • 966
  • 1
  • 8
  • 26

2 Answers2

23

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.

chris
  • 60,560
  • 13
  • 143
  • 205
  • Yes, that was the problem. I didn't see that the other question uses struct. – Dejan Jul 06 '18 at 11:56
  • 2
    Chris, it might be worth adding the virtual destructor to Base. As it stands, this is would result in UB in the above use case as Derived would not be properly destructed. – Richard Hodges Jul 06 '18 at 12:09
-1

The pattern is often used in pimpl idiom, so virtual destructor is necessary.

ashishk
  • 67
  • 5
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 09 '22 at 20:56