std::shared_ptr and Inheritance

boost, c++, c++11, inheritance, shared-ptr

Solution

As far as I can tell, the code that you've presented compiles fine: http://ideone.com/06RB2W

#include <memory>

class Base {
    public:
        Base() = default;
        virtual ~Base() = default;
        virtual void run() = 0;
};

class Derived1: public Base {
    public:
        Derived1() = default;
        virtual ~Derived1() = default;
        void run() {}
};

class Derived2: public Base {
    public:
        Derived2() = default;
        virtual ~Derived2() = default;
        void run() {}
};

void doSomething(std::shared_ptr<Base> ptr) {
    ptr->run();
}

int main() {
    doSomething(std::make_shared<Derived1>());
    doSomething(std::make_shared<Derived2>());
}

Problem

I am having some problems with automatic typecasting between `shared_ptr` of inherited classes. My class structure is as follows, a base class `Base` and two derived classes `Derived1` and `Derived2`. ``` // Base class class Base { protected: ... ... public: Base() = default; virtual ~Base() = default; virtual void run() = 0; ... ... }; // Derived class class Derived1: Base { protected: ... ... public: Derived1() = default; virtual ~Derived1() = default; void run() {...} ... ... }; // Derived class class Derived2: Base { protected: ... ... public: Derived2() = default; virtual ~Derived2() = default; void run() {...} ... ... }; ``` I have a function `doSomething()` ``` void doSomething(std::shared_ptr<Base> ptr) { ptr->run(); ... } ``` I call the function with the derived classes like so - ``` doSomething(make_shared<Derived1>()) doSomething(make_shared<Derived2>()) ``` But I get an error saying - ``` no viable conversion from 'shared_ptr<class Derived1>' to 'shared_ptr<class Base>' no viable conversion from 'shared_ptr<class Derived1>' to 'shared_ptr<class Base>' ``` What am I doing wrong? Is it safe just to use `static_pointer_cast` to the Base type? Like - ``` doSomething(static_pointer_cast<Base>(make_sahred<Derived2>())) ``` SOLUTION My bad... The problem was that I was inheriting the base class privately.

Original source