【问题标题】:std::dynamic_pointer_cast of std::shared from base to derived returns NULLstd :: dynamic_pointer_cast of std ::从基础共享到派生返回null
【发布时间】:2015-11-27 03:37:45
【问题描述】:

我有一个函数接受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";
    }

}

函数创建派生对象并调用函数:

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

任何帮助将不胜感激。

编辑:更正错字

【问题讨论】:

  • 当然。 msg_ptr 构造为 Base,而不是 Derived
  • 另外,您的意思是将msg_ptr 传递给callback(),请将您的示例清理为minimal, complete, and verifiable
  • 什么是“NULL 类型”?
  • NULL 类型是我的一个不好的命名习惯。我已经在问题中更改了它。

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


【解决方案1】:

你完全是在切片。您的动态分配的对象(由该共享指针管理)只是一个从派生构造的基础副本。事后你不能“取回衍生品”,就像你不能设计一辆只有一个轮子的跑车一样。

我认为您在这里的主要困惑在于认为make_shared 会共享某些内容。它没有。它创造了一些可以分享的新东西。

【讨论】:

  • 你完全正确!我完全误解了make_shared。我现在已经更正了。我从未将 make_shared/unique 等同于 new。
  • @John:伙计别担心;这是 C++ 的错,不是你的。这种语言一直非常愚蠢,而且一天比一天更加愚蠢。我希望这样的页面能够推动开花委员会。
【解决方案2】:

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

在你的例子中,它创建了一个 Base 类型的对象,并给它一个 Derived 的实例。比调用 Base 复制构造函数,传递的 Derived 对象隐式转换为对 Base 的 const 引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    相关资源
    最近更新 更多