std::shared_ptr и наследование

#c #inheritance #c 11 #boost #shared-ptr

#c #наследование #c 11 #повышение #shared-ptr

Вопрос:

У меня возникли некоторые проблемы с автоматическим приведением типов между shared_ptr унаследованными классами.

Структура моего класса следующая: базовый класс Base и два производных класса Derived1 и 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() {...}
  ...
  ...
};
  

У меня есть функция doSomething()

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

Я вызываю функцию с производными классами следующим образом —

 doSomething(make_shared<Derived1>())
doSomething(make_shared<Derived2>())
  

Но я получаю сообщение об ошибке —

 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>'
  

Что я делаю не так? Безопасно ли просто использовать static_pointer_cast для базового типа? Нравится —

 doSomething(static_pointer_cast<Base>(make_sahred<Derived2>()))
  

РЕШЕНИЕ
Виноват… Проблема заключалась в том, что я наследовал базовый класс частным образом.

Ответ №1:

Насколько я могу судить, представленный вами код отлично компилируется: 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>());
}
  

Комментарии:

1. Извините, что я виноват… Я наследовал класс частным образом в своем коде! Это была действительно ошибка новичка!

2. Преобразует ли shared_ptr автоматически (без какого-либо приведения типов) в базовый класс shared_ptr? Имеют ли они одинаковое количество ссылок?

3. Он не вводит приведение автоматически, но если вы приведете его вручную, то количество ссылок будет общим.

4. В вашем коде вы не вводили приведение вручную, поэтому они разделяют количество ссылок?