2012-04-22 108 views
4

我想使用shared_ptr就像我會使用一個實際的指針。我希望能夠做到像shared_ptr空指針和分配

shared_ptr<int> a; 
a = new int(5); 
a = 0; 
shared_ptr<int> foo() 
    return 0; 

但它沒有默認實現。

我通過添加

template<class Y> void operator=(int i) 
{ 
    reset(i); 
} 
template<class Y> void reset(int i) 
{ 
    this_type(i).swap(*this); 
} 
template<class Y> void operator=(Y * p) 
{ 
    reset(p); 
} 
shared_ptr(int i): px(0), pn() 
{ 
} 

改變升壓庫的shared_ptr的源代碼的唯一事情是,如果我做= -1;它會編譯並給我一個空指針,這應該不成問題,因爲通常你不能給一個指針賦一個整數值。

所以我的問題是,這是爲了實現這個還是有我忘了,可能會導致應用程序崩潰的情況下正確的方法是什麼?因爲在我看來,我看到爲shared_ptr獲取空指針的唯一方式是調用默認的構造函數,這在代碼中不是很優雅,與之相比:ptr = 0 ;.

+0

文字上的'0'是一個_null指針常量_已經可以隱式轉換爲任何指針類型的_null指針值_。 – 2012-04-22 08:27:24

+1

+1「我更改了boost庫的shared_ptr的源代碼」;) – Offirmo 2013-02-06 11:58:35

+0

爲什麼不使用C++ 11'nullptr'代替? – Venemo 2014-03-09 13:15:16

回答

24

不要更改源。這就像是出於某種原因,非常聰明的人已經決定,它的定義方式比任何你想要編輯的方式都要好。

你有什麼,甚至沒有任何意義。你不能給一個指針賦一個整數,它們是兩種不同的類型,但你已經給了它這樣的語義。你說:「......這不應該是一個問題,因爲通常你不能指定一個整數值給一個指針」,但你也在問題的頂部說道:「我想用shared_ptr就像我一樣使用實際指針「。那麼,這是什麼?由於將指向整數的指針設置爲null,因此您可以獲得與實際指針差不多的距離。

你需要退後一步,實現你想要的東西並不總是最好的事情。您應該恢復這些更改並正確使用該類。我不想說卑鄙,但這不是你想要走的路線;它很危險,具有無意義的語義,並且全都無法維護。

+0

是的,你說得對。我想我只是懶惰,因爲我不想改變一切,因爲我有正常的指針之前,並正在改變爲智能ptr。 我懷疑我在做什麼是錯誤的,這就是爲什麼我問:) – 2012-04-22 08:33:22

+0

@MichaelFerris:這沒關係,但有時你只需要開始工作,尤其是在重構代碼時。 :)隨着你的編碼風格的提高,你會發現最好清楚一些事情。雖然隱含的功能對您而言意味着更少的工作,但通常意味着您的清晰度和安全性會降低。例如,只要看一下'return 0;',你會認爲你返回的是* number *零,而不是一個空指針。但是當你說'return boost :: shared_ptr ();'時沒有混淆。事實上,這很大程度上是爲了讓新的C++標準爲null引入一個新的關鍵字:'nullptr'。 – GManNickG 2012-04-22 08:39:46

+0

我甚至不知道nullptr的存在。謝謝! :) 另外,我選擇使用標準庫中的shared_ptr,所以我不必攜帶像boost這樣的巨大庫。還有很多東西要學習;) – 2012-04-22 08:47:05

8

shared_ptr實現了一個類似指針的接口,因此您可以使用*->運算符。

內部默認構建的(空的)shared_ptr將等於nullptr,因此您無需擔心顯式指定。即

std::shared_ptr<int> sh; 
std::cout << (sh.get() == nullptr) << std::endl; 

// Or alternatively: 
std::cout << (sh == nullptr) << std::endl; 

另外,(在我看來)使用的shared_ptr創建對象的最優雅的方式是std::make_shared功能。這也有被一些編譯器會更有效(至少在MSVC++)由於衆所周知的一些內部優化的附加效益爲「我們知道你住的地方成語」

#include <memory> 
#include <string> 

class foo 
{ 
public: 
    foo(std::string s, int n) {} 
}; 

int main() 
{ 
    auto p = std::make_shared<int>(); 
    auto q = std::make_shared<foo>("hello", 2); 
}