Как реализовать полиморфизм с помощью 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);