Search code examples
c++smart-pointers

What is the syntax for make_unique for a pointer of base type to a derived object?


Consider the following base and derived classes.

class base
{
public:
    int i{9};
    virtual void func()
    {
        cout << "base" << endl;
    }
    virtual ~base()
    {

    }
};

class derived : public base
{
public:
    int i{4};
    void func()
    {
        cout << "derived" << endl;
    }

};

I would like to create a unique_ptr of base type to derived object. I know I can do

std::unique_ptr<base> ptr{new derived};

but when I do

auto ptr = std::make_unique<base>(derived{});
ptr->func();

this prints base, which is not my intended behavior. What is the correct way to use std::make_unique for this case? In addition, why does auto ptr = std::make_unique<base>(derived{}) do?


Solution

  • When you do

    auto ptr = std::make_unique<base>(derived{});
    

    make_unique<base> is going to create a unique_ptr<base> which means it is only going to create a base object. Since derived is derived from base it is legal to pass that to base's copy constructor so the code compiles, but you have a base, not a derived.

    What you would need is

    std::unique_ptr<base> ptr = std::make_unique<derived>();
    

    to get a base pointer that points to a derived object. This isn't the syntax you want, but it works correctly.

    If you used

    auto ptr = std::make_unique<derived>();
    

    then ptr would be a std::unique_ptr<derived>, not a std::unique_ptr<base>.