Как реализовать полиморфизм с помощью std:: shared ptr?

Я видел некоторые другие вопросы по этой теме, но до сих пор не нашел ответа-я думаю, что мне чего-то не хватает:

я определил два простых тестовых класса:

class TestBase
{

  public:

    TestBase ( ) { };
    ~ TestBase ( ) { };

  protected:

    inline virtual int getInt ( )
    {
        return 0;
    }

};

class TestDerived : public TestBase
{

  protected:

    inline int getInt ( ) override
    {
        return 1;
    }

};

я объявил typedefs, чтобы упростить их использование с std::shared_ptr:

typedef std::shared_ptr<TestBase> spBase;
typedef std::shared_ptr<TestDerived> spDerived;

проблема: я не могу скомпилировать код для использования этих shared_ptr объявления полиморфно, хотя base во всех этих случаях на самом деле является экземпляром spDerived:

spBase base;
spDerived derived = static_cast < spDerived > ( base );

ошибка: нет подходящей функции для вызова ‘с std::shared_ptr::shared_ptr(spBase&)

spDerived derived = dynamic_cast < spDerived > ( base );

ошибка: база не динамическое приведение dynamic_cast ‘’ (из spBase тип ‘{ака классом std::shared_ptr}’) в spDerived тип ‘{класс ака std:: shared_ptr} ' (цель не является указателем или ссылкой)

spDerived derived = static_pointer_cast < spDerived > ( base );

ошибка: преобразование из ' std:: shared_ptr >’ к не скалярному типу ’ spDerived {aka std::shared_ptr} ' запрошено

spDerived derived = dynamic_pointer_cast < spDerived > ( base );

ошибка: преобразование из ' std:: shared_ptr >’ в не скалярный тип ’ spDerived {aka std::shared_ptr} ' запрошено

я использую C++11 в Ubuntu 14.04 с цепочкой инструментов GCC по умолчанию. Компилятор-это GCC-4.9. Что я делаю не так? Нельзя ли использовать shared_pointer полиморфно?

1 ответов


тип передан в std::static_pointer_cast и std::dynamic_pointer_cast поскольку аргумент шаблона первого типа является типом самого преобразованного типа указателя, а не умный указатель типа:

static_pointer_cast<T>(arg);
                .~~~^  
                v 
template <class T, class U> 
           .~~~~^  
           v 
shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r);


dynamic_pointer_cast<T>(arg);
                .~~~~^  
                v 
template <class T, class U> 
           .~~~~^  
           v 
shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r);

С этим сказано, вы можете назвать его, как показано ниже:

spBase base = std::make_shared<TestDerived>();
spDerived derived = std::dynamic_pointer_cast<spDerived::element_type>(base);
// or:
spDerived derived2 = std::dynamic_pointer_cast<TestDerived>(base);