Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::shared_ptr and Inheritance

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.

like image 607
ssb Avatar asked Jul 07 '14 05:07

ssb


People also ask

Why is shared_ptr unique deprecated?

What is the technical problem with std::shared_ptr::unique() that is the reason for its deprecation in C++17? this function is deprecated as of C++17 because use_count is only an approximation in multi-threaded environment.

What is the difference between Make_shared and shared_ptr?

The difference is that std::make_shared performs one heap-allocation, whereas calling the std::shared_ptr constructor performs two.

Is shared_ptr slow?

Admittedly, the std::shared_ptr is about two times slower than new and delete. Even std::make_shared has a performance overhead of about 10%.

What happens when you move a shared_ptr?

By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).


1 Answers

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>());
}
like image 93
Bill Lynch Avatar answered Sep 22 '22 13:09

Bill Lynch