如何使用std :: shared_ptr实现多态?

Vec*_*tor 15 polymorphism gcc casting shared-ptr c++11

我已经看到了关于这个主题的一些其他问题,但仍然没有找到答案 - 我想我错过了一些东西:

我定义了两个简单的测试类:

class TestBase
{

  public:

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

  protected:

    inline virtual int getInt ( )
    {
        return 0;
    }

};

class TestDerived : public TestBase
{

  protected:

    inline int getInt ( ) override
    {
        return 1;
    }

};
Run Code Online (Sandbox Code Playgroud)

我声明了typedef来简化它们的使用 std::shared_ptr:

typedef std::shared_ptr<TestBase> spBase;
typedef std::shared_ptr<TestDerived> spDerived;
Run Code Online (Sandbox Code Playgroud)

问题:我无法编译代码以shared_ptr多态方式使用这些声明,即使base在所有这些情况下实际上是一个实例spDerived:

spBase base;
spDerived derived = static_cast < spDerived > ( base );
Run Code Online (Sandbox Code Playgroud)

错误:没有匹配函数来调用'std :: shared_ptr :: shared_ptr(spBase&)

spDerived derived = dynamic_cast < spDerived > ( base );
Run Code Online (Sandbox Code Playgroud)

错误:不能dynamic_cast'base'(类型'spBase {aka class std :: shared_ptr}')输入'spDerived {aka class std :: shared_ptr}'(target不是指针或引用)

spDerived derived = static_pointer_cast < spDerived > ( base );
Run Code Online (Sandbox Code Playgroud)

错误:从'std :: shared_ptr>'转换为非标量类型'spDerived {aka std :: shared_ptr}''

spDerived derived = dynamic_pointer_cast < spDerived > ( base );
Run Code Online (Sandbox Code Playgroud)

错误:从'std :: shared_ptr>'转换为非标量类型'spDerived {aka std :: shared_ptr}''

我在带有默认GCC工具链的Ubuntu 14.04盒子上使用C++ 11.编译器是gcc-4.9.我究竟做错了什么?不能以多态方式使用shared_pointer吗?

Pio*_*cki 17

传入std::static_pointer_caststd::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);
Run Code Online (Sandbox Code Playgroud)

话虽如此,你可以像下面这样称呼它:

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);
Run Code Online (Sandbox Code Playgroud)