Search code examples
c++oopinterfacederived-class

shared_ptr to derived class from a specific base class


I feel like this is a pretty basic C++ question. I am trying to make a class which contains a member variable which is a shared_ptr to any class which is derived from a specific interface, but does not care which particular derived class it is. I am implementing it as follows:


class Base
{
public:
  Base();
  virtual void do_stuff() = 0;
};

class Derived : Base {
  Derived() {}
  void do_stuff() { };
};


class Foo
{

public:
  Foo() {
    mPtr = std::make_shared<Derived>();
  }

protected:
  std::shared_ptr<Base> mPtr;
};

Compiling gives the following error at the top:

error: no match for ‘operator=’ (operand types are ‘std::shared_ptr<Base>’ and ‘std::shared_ptr<Derived>’)
     mPtr = std::make_shared<Derived>();

What's the proper way to do this?

Edit: Changing inheritence from Base to public Base made it work. However, trying to instantiate the class makes the linker break.


Foo foo;

Compiling gives

libfoo.so: undefined reference to `Base::Base()'
collect2: error: ld returned 1 exit status

What's this about?


Solution

  • Fixed the access specifiers and more:

    #include <memory>
    
    class Base {
    public:
        Base() = default;            // must have implementation
    
        // virtual dtor - not strictly needed for shared_ptr:
        virtual ~Base() = default;
        virtual void do_stuff() = 0;
    };
    
    class Derived : public Base {    // public inheritance
    public:                          // public access
        // Derived() {}              // not needed
        void do_stuff() override {}; // mark override 
    };
    
    class Foo {
    public:
        Foo() :
            mPtr{std::make_shared<Derived>()} // use the member init-list
        {}
    
    private:                         // prefer private member variables
        std::shared_ptr<Base> mPtr;
    };