c++unique-ptr

Assign unique_ptr of derived class to a base class


Why this code doesn't compile?

#include <memory>
    
struct Base {
};
    
struct Derived: Base {
    int n;
};
    
int main() {
    std::unique_ptr<Base> base_ptr = std::make_unique<Derived>(5);
}

I looked into unique_ptr sources and it looks like it allows moving unique_ptrs of derived classes https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/unique_ptr.h#L368

I need this so I can collect messages of different type if a collection to futher work with them

The compiler outputs:

/usr/include/c++/13/bits/unique_ptr.h:1070:30: error: could not convert ‘std::forward<int>((* & __args#0))’ from ‘int’ to ‘arb::exchange_connector::Base’
  1070 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }

Solution

  • It has nothing to do with the class hirarchy, but with the fact that Derived is an aggregate and you cannot use make_unique for aggregate initialization like that.

    Your code will also similarly fail to compile with a std::unique_ptr<Derived>:

    std::unique_ptr<Derived> ptr = std::make_unique<Derived>(5);
    

    One solution is to add a constructor to Derived.

    Another issue in your code is that in order to properly destruct a Derived through a Base pointer, you must anyway add a virtual destructor to Base.

    Both are shown below:

    #include <memory>
    
    struct Base {
        // Add a virtual destructor:
        virtual ~Base() {}
    };
    
    struct Derived : Base {
        // Add this constructor:
        Derived(int n_) : n(n_) {}
    
        int n;
    };
    
    int main() {
        std::unique_ptr<Base> base_ptr = std::make_unique<Derived>(5);
    }
    

    Live demo.