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

28

我看到了其他关于这个主题的问题,但仍然没有找到答案 - 我想我错过了什么:

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

class TestBase
{

  public:

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

  protected:

    inline virtual int getInt ( )
    {
        return 0;
    }

};

class TestDerived : public TestBase
{

  protected:

    inline int getInt ( ) override
    {
        return 1;
    }

};

我声明了typedef以简化它们与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 );

error: no matching function for call to ‘std::shared_ptr::shared_ptr(spBase&)

spDerived derived = dynamic_cast < spDerived > ( base );

error: cannot dynamic_cast ‘base’ (of type ‘spBase {aka class std::shared_ptr}’) to type ‘spDerived {aka class std::shared_ptr}’ (target is not pointer or reference)

spDerived derived = static_pointer_cast < spDerived > ( base );

error: conversion from ‘std::shared_ptr >’ to non-scalar type ‘spDerived {aka std::shared_ptr}’ requested

spDerived derived = dynamic_pointer_cast < spDerived > ( base );

error: conversion from ‘std::shared_ptr >’ to non-scalar type ‘spDerived {aka std::shared_ptr}’ requested

我正在使用默认的GCC工具链,在Ubuntu 14.04上使用C++11。编译器是gcc-4.9。 我做错了什么?shared_pointer不能用于多态吗?


7
static_pointer_cast<spDerived::element_type>(base) - Piotr Skotnicki
2
这就是为什么像那样的typedef是一个可怕的想法。它们只会使代码变得更加混乱。 - Puppy
@小狗 - 我非常讨厌打字,但我担心你是正确的。 - Vector
1
@PiotrSkotnicki 你救了我的一天! - user392412
1个回答

26

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);

话虽如此,您可以按以下方式调用:

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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接