【问题标题】:Cannot convert from 'const shared_ptr<base_class>' to 'shared_ptr<derived_class>'无法从 'const shared_ptr<base_class>' 转换为 'shared_ptr<derived_class>'
【发布时间】:2018-12-02 13:17:51
【问题描述】:

我已经声明了以下vector

vector<shared_ptr<base_class> inventory;

我有以下变量:

shared_ptr<derived_class> equipped_item;

我正在尝试执行以下操作:

equipped_item = inventory[0];

我收到以下错误:

Cannot convert from 'const shared_ptr<base_class>' to 'shared_ptr<derived_class>'

我的问题是为什么不允许我尝试将equipped_item 设置为vector 中的选定项目?

【问题讨论】:

    标签: c++ class c++11 smart-pointers stdvector


    【解决方案1】:

    由于base_class 不能隐式转换为derived_class,因此常规构造函数将不起作用。你应该使用static_pointer_cast(如果类不是多态的)或dynamic_poiner_cast(如果类是多态的):

    ::std::vector<::std::shared_ptr<base_class>> pointers{::std::make_shared<derived_class>()};
    ::std::shared_ptr<derived_class> pd{::std::static_pointer_cast<derived_class>(pointers[0])};
    

    请注意,需要从基类转换为派生类通常是类层次结构不正确或接口使用不正确的标志。

    【讨论】:

    • @PaulSanders 因为 shared_ptr 构造函数接受对 shared_ptr 的 const 限定的左值引用(这就像一个复制构造函数)。来自其他重载集的构造函数接受对 shared_ptr 的非 const 限定右值引用(像构造函数一样移动),因为 pointers[0] 产生左值,所以此处不考虑。
    • 好的,谢谢。 gcc 详细说明,请参阅here
    【解决方案2】:

    您正在尝试执行以下操作:

    pointer_derived =  pointer_base; //No implicit conversion possible.
    

    但是以下是可能的:

    pointer_base = pointer_derived; // Possible.
    

    尝试显式地向下转换您的pointer_base。

    pointer_derived =  static_pointer_cast<Derived>(pointer_base);
    //Since you know that pointer_base is pointing to a derived class here.
    

    【讨论】:

      【解决方案3】:

      您正在尝试将 base 类转换为不可隐式转换的 derived(down-cast)。为此,您需要std::static_pointer_cast(如果您确定要转换的内容)或std::dynamic_pointer_cast(如果该类是多态的),因为您使用了smart pointers

      例如以下是std::static_pointer_cast 的示例代码:

      #include <iostream>
      #include <vector>
      #include <memory>
      
      class base_class    {};
      class derived_class: public base_class {};
      
      int main()
      {
          std::shared_ptr<derived_class>  some_derived_ptr = std::make_shared<derived_class>();
      
          std::vector<std::shared_ptr<base_class>> inventory{some_derived_ptr};
      
          std::shared_ptr<derived_class>
                      equipped_item = std::static_pointer_cast<derived_class>(inventory[0]);
      }
      

      【讨论】:

        【解决方案4】:

        cppreference,从YTshared_ptr 转换构造函数“如果Y* 不能隐式转换为T*,则不参与重载决议”。您正在执行从基础到派生的转换,这需要 static_castdynamic_cast,这不是隐式的。

        您应该使用pointer caststatic_pointer_castdynamic_pointer_cast,具体取决于您的类定义。

        【讨论】:

          猜你喜欢
          • 2017-08-06
          • 1970-01-01
          • 1970-01-01
          • 2018-07-16
          • 2019-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-22
          相关资源
          最近更新 更多