2009-09-03 133 views
36

我在我的程序中使用boost共享指針,並且我有一個類作爲參數引用另一個對象。我碰到的問題是make_shared函數要求所有參數都是一個const引用,如果我的類的構造函數不允許const引用參數傳入,我會得到編譯錯誤。boost make_shared接受一個const引用。任何方式來解決這個問題?

有沒有人知道背後的原因這個?另外,我能做些什麼來解決這個問題嗎?什麼是給我的問題

代碼示例:

class Object 
{ 
    public: 
    Object(int& i) 
    { 
     i = 2; 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    int i = 0; 
    boost::shared_ptr<Object> obj = boost::make_shared<Object>(i); 
    return 1; 
} 

這導致指出以下

編譯器錯誤:make_shared.hpp:185:錯誤:沒有匹配函數調用`對象:對象(const int的&)」 注:考生:對象:對象(const對象&) 注:對象:對象(INT &)

如果對象構造函數的參數是一個const int,則可以使用。我很好奇爲什麼make_shared的行爲如此。

+0

你能告訴我們一些代碼來演示如何使用'make_shared()'嗎? – quamrana 2009-09-03 15:06:48

+0

的代碼片段發佈 – 2009-09-03 15:20:58

回答

42

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/make_shared.html說:「如果您需要將非const引用傳遞給T的構造函數,則可以通過將參數包裝到boost :: ref調用中來實現。該頁面上的其他文字似乎支持RüdigerHanke的回答。

+0

真棒,謝謝我真的不想在下面使用我的解決方法。 – 2009-09-03 15:58:37

0

雖然我仍然不知道爲什麼提高make_shared對我施加這個限制,我找到了解決辦法。如果我將const引用傳遞給參數的指針,那麼我可以更改指針。這裏是代碼片段:

class Object 
{ 
    public: 
    Object(int* const& i) 
    { 
     *i = 2; 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    int i = 0; 
    boost::shared_ptr<Object> obj = boost::make_shared<Object>(&i); 
    cout << i << "\n"; 
    return 1; 
} 

這一個就像一個魅力。任何人都有任何想法,爲什麼我需要跳過這些箍?對於make_shared來說似乎很奇怪,因爲這個限制對我來說很重要,儘管我認爲這在大多數情況下可能是一個壞主意。

8

不能說他的功能的作者,但是...你必須做出選擇。如果該函數使用非const引用,那麼您無法將const對象傳遞給採用const引用的構造函數。

根據我的經驗,採用const引用的構造函數比採用可變引用的構造函數要普遍得多。

構造函數可以有n參數,所以你不能只提供一個單一的重載,但必須考慮到const/non-const的任何組合,這會導致你需要的重載指數爆炸, d想要爲它們提供重載。 C++ 0x和完美的轉發應該爲我認爲的這個問題提供一個解決方案。

+0

完美的解釋。謝謝。 – 2009-09-03 15:57:45

1

您需要定義一個複製構造函數。

class Object 
{ 
    public: 
    Object(const Object& original) 
    { 
     // Copy original to new object 
     // The reason for the const is this should not change the original 
    }; 

    Object(int& i) 
    { 
     i = 2; 
    } 
}; 
4

直到rvalue references(參見「轉發問題」一節)到達C++ 0x中,完美的轉發是不可能的。 make_shared只是盡其所能地做到最好。

+0

+1有人實際上發佈了一個解釋,爲什麼這是,而不僅僅是使用boost :: ref(..):) – Nils 2013-12-06 17:58:46

0

您可以通過使對象構造函數explicit來修復它。