从base到derived的std :: dynamic_pointer_cast std :: shared返回NULL

时间:2015-09-01 19:25:16

标签: c++ c++11 casting shared-ptr smart-pointers

我有一个函数接受类型为Base的共享指针,然后std::dynamic_pointer_cast为派生类型。但是,派生指针是NULL,我不明白为什么。我确保在我的基类中包含一个虚拟析构函数。我不想使用静态转换,因为这不能保证我的派生成员变量和函数被保留?

代码如下:

基类:

class Base
{
public:
    mType get_type()
    {
        return msg_type;
    }

    void set_type(mType type)
    {
        msg_type = type;
    }

    virtual ~cMsg() = default;
protected:
    mType msg_type;
    message msg;
};

派生类:

class Derived : public Base
{
public:
    void set_i(int j)
    {
        i = j;
    }

    int get_i()
    {
        return i;
    }
private:
    int i;
};

执行演员表演的功能:

void callback(std::shared_ptr<Base> msg_received)
{
    std::cout<< "Callback called\n";
    auto real_msg = std::dynamic_pointer_cast<Derived>(msg_received);

    if (real_msg != NULL)
    {
        std::cout << "i value is: " << real_msg->get_i() << "\n";
    }

}

创建Derived对象并调用函数的函数:

int main()
{  
    Derived test_msg;

    test_msg.set_i(1);    
    test_msg.set_type(mSystem::TEST_MSG);

    std::shared_ptr<Base> msg_ptr = std::make_shared<Base>(test_msg);    

    callback(msg_ptr);

    return 0;
}

任何帮助都将不胜感激。

编辑:纠正错字

2 个答案:

答案 0 :(得分:2)

你完全切片了。您的动态分配对象(由该共享指针管理)只是一个Base,从Derived构造的副本。你不能得到Derived&#34;之后,你可以设计一款仅为其中一个轮子设计施工计划的跑车。

我认为你在这里的关键混淆是认为make_shared分享了一些东西。它没有。它创造了一些新的东西,将被分享。

答案 1 :(得分:1)

您正在创建Base类型的shared_ptr,即使您为它提供了Derived类型的对象。请记住,所有make_shared都会(在使用allocator分配内存之后)调用使用提供给make_shared的参数指定的类型的构造函数。

在您的情况下,它创建一个Base类型的对象,并为其提供Derived实例。然后调用基本复制构造函数,传递Derived对象,隐式转换为对Base的const引用。