2015-02-24 94 views
0

我想一個shared_ptr<derived>添加到地圖shared_ptr<base>值(如下http://ideone.com/hd68yc),但它失敗(我們到達EXIT_FAILURE):爲什麼我無法在此代碼中將shared_ptr <Derived>添加到地圖<key_type,shared_ptr <Base>>?

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

回答

-1

一開始,在派生類中包含一個額外setting成員。擺脫這一點,我發現我不能使用ctor語法,因爲它指的是一個被繼承的setting成員。

最後,使用下面的固定我的問題:

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

這可能不是最有趣的問題和答案,但我花了很多時間做一個MVCE,我想我可能會從中得到一些東西! – 2015-02-24 14:44:16

+3

您可能應該將正確的值傳遞給基礎構造函數,而不是使用默認值:'correct_derived(const int&s):base(s){} – dewaffled 2015-02-24 14:49:30

+0

是的,這很合理,謝謝。在實際的代碼中'derived'是谷歌模擬的另一個派生於'base'的類,所以我想我最初試圖保持測試代碼和被測單元是分開的。 – 2015-02-24 14:57:19

-1
m_s.insert(make_pair("Name",make_shared<derived>(4))); 

if(4 == m_s.at("Name")->setting) { 

至於我可以告訴你存儲一個指針在一張地圖,然後把它比作一個int(4)。您將不得不取消引用存儲的共享指針以獲取其值,然後可以將其與'4'進行比較。這可能是您最終遇到EXIT_FAILURE的原因。

+0

我同意,但代碼是一種人爲的例子,我使用指針,因爲地圖中的值(在真實代碼中)具有虛擬功能。 – 2015-02-24 15:05:39

+1

爲什麼OP需要一個指針與問題無關,他可能有一些原因在MCVE中不可見。 – Slava 2015-02-24 15:05:48

1

無法初始化構造函數初始化列表中基類成員,但你可以調用適當的基類構造函數:

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

你天真「修復」把會員setting到派生類不解決這個問題,但隱藏它,允許代碼編譯,但打破邏輯。

相關問題