【问题标题】:Why can't I add a shared_ptr<Derived> to a map<key_type,shared_ptr<Base>> in this code?为什么我不能在此代码中将 shared_ptr<Derived> 添加到 map<key_type,shared_ptr<Base>> ?
【发布时间】:2015-02-24 14:43:56
【问题描述】:

我想将shared_ptr&lt;derived&gt; 添加到具有shared_ptr&lt;base&gt; 值的地图中(如下http://ideone.com/hd68yc)但它失败了(我们到达EXIT_FAILURE):

#include <iostream>
#include <map>
#include <memory>
using namespace std;

class base{
    public:
        base(const int& s = 1):setting{s}{};
        int setting;
};
class derived : public base{
    public:
        derived(const int& s):setting{s}{};
        int setting;
};

int main() {
    map<string,shared_ptr<base>> m_s;
    m_s.insert(make_pair("Name",make_shared<derived>(4)));
    // None of these worked either...
    //m_s.emplace("Name",make_shared<derived>(4));
    //m_s["Name"] = make_shared<derived>(4);

    if(4 == m_s.at("Name")->setting){
        return EXIT_SUCCESS;
    }else{
        cout << "setting is " << m_s.at("Name")->setting << " when 4 expected";
        return EXIT_FAILURE;
    }
}

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    你不能在构造函数初始化列表中初始化基类成员,但你可以调用正确的基类构造函数:

    class derived : public base{
        public:
            derived(const int& s):base{s}{};
    };
    

    您将成员setting 放入派生类的天真“修复”并不能解决问题,而是将其隐藏,允许代码编译,但会破坏逻辑。

    【讨论】:

      【解决方案2】:

      首先,派生类包含一个额外的setting 成员。摆脱这一点表明我不能使用 derived(const int&amp; s):setting{s}{}; ctor 语法,因为它引用了继承的 setting 成员。

      最后,使用以下解决了我的问题:

      class correct_derived : public base{
          public:
              correct_derived(const int& s){
                  setting = s;
              }
      };
      

      【讨论】:

      • 这可能不是最有趣的问题和答案,但我花了很多时间制作一个 MVCE,我想我不妨从中得到一些东西!
      • 您可能应该将正确的值传递给基本构造函数,而不是使用默认值:correct_derived(const int&amp; s) : base(s) { }
      • 是的,这是有道理的,谢谢。在实际代码中,derived 是从base 派生的另一个类的谷歌模拟,所以我想我最初试图将测试代码和被测单元分开。
      【解决方案3】:
      m_s.insert(make_pair("Name",make_shared<derived>(4)));
      
      if(4 == m_s.at("Name")->setting) {
      

      据我所知,将指针存储在地图中,然后将其与 int (4) 进行比较。您必须取消引用存储的共享指针以获取其值,然后您可以将其与“4”进行比较。这可能是您最终到达 EXIT_FAILURE 的原因。

      【讨论】:

      • 我同意,但代码是一种人工示例,我使用指针是因为映射中的值(在实际代码中)具有虚函数。
      • 为什么 OP 需要指针与问题无关,他可能有 MCVE 看不到的原因。
      猜你喜欢
      • 2012-11-04
      • 1970-01-01
      • 2021-02-04
      • 2017-08-06
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      相关资源
      最近更新 更多