2013-01-01 29 views
1
#include <iostream> 
#include <boost/shared_ptr.hpp> 

class implementation 
{ 
public: 
    ~implementation() { std::cout <<"destroying implementation\n"; } 
    void do_something() { std::cout << "did something\n"; } 
}; 

void test() 
{ 
    boost::shared_ptr<implementation> sp1(new implementation()); 
    std::cout<<"The Sample now has "<<sp1.use_count()<<" references\n"; 

    boost::shared_ptr<implementation> sp2 = sp1; 
    std::cout<<"The Sample now has "<<sp2.use_count()<<" references\n"; 

    sp1.reset(); 
    std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" references\n"; 

    sp2.reset(); 
    std::cout<<"After Reset sp2.\n"; 
} 

int main() 
{ 
    test(); 
} 

運行結果不清楚低於:東西在這個shared_ptr的例子

$ ./a.out 
The Sample now has 1 references 
The Sample now has 2 references 
After Reset sp1. The Sample now has 1 references 
destroying implementation 
After Reset sp2. 

請檢查上面的代碼。我不清楚的第一件事是,下面的句子是什麼意思?所以sp1是一個指針?一個函數?或者一個指向函數的指針?和new implementation()意味着什麼? sp1()的參數?

boost::shared_ptr<implementation> sp1(new implementation()); 

第二個問題是,destroying implementation給出的sp1.reset()sp2.reset()的結果。但是,如果sp1.reset()被註釋掉,那麼結果將是:

$ ./a.out 
The Sample now has 1 references 
The Sample now has 2 references 
After Reset sp1. The Sample now has 2 references 
After Reset sp2. 
destroying implementation 

如果我們只註釋掉sp2.reset(),那麼結果將是:

$ ./a.out 
The Sample now has 1 references 
The Sample now has 2 references 
After Reset sp1. The Sample now has 1 references 
After Reset sp2. 
destroying implementation 

所以沒有必要同時調用sp1.reset()sp2.reset()釋放shared_ptr,我是對不對?

+3

你不需要調用'reset'來釋放指針**,你可以使用'reset'來改變智能指針當前指向的內容。您可以將它想象爲一個常規指針的賦值運算符。 –

+5

如果你不知道'new x()'做了什麼,你需要了解指針。如果你不知道共享指針是什麼,你需要了解智能指針。沒有簡單的答案比實際閱讀更有益。 – chris

+0

在試圖理解C++'shared_ptr'之前,至少可以想象你應該先學習另一種語言。根據「Python自動執行的操作」或「在語言X中執行相同的操作'try'/ finally'執行相同的操作,這要比從頭開始解釋它要容易得多。」 – abarnert

回答

2

我不清楚的第一件事是,下面的句子是什麼意思?所以sp1是一個指針?一個函數?或者一個指向函數的指針?

spshared_ptr<implementation>。如果您不知道這意味着什麼,那麼請參閱參考文檔和教程。但簡短版本是:這是一個與implementation *指針類似的對象,只不過它會在您完成對象時自動刪除implementation對象。這就是它成爲「智能指針」的原因。 A shared_ptr是一種特定類型的智能指針,可讓您根據需要製作任意數量的副本,並且只在所有這些副本都消失時才刪除底層對象。

看起來像這樣的一種方式是它爲您提供了一種不需要垃圾回收器的簡單垃圾回收形式。

查看它的另一種方法是作爲C++中央成語之一​​(RAII)的一部分。

和新的實現()意味着什麼? sp1()的參數?

new implementation()創建一個新implementation對象,調用它的默認構造函數,並返回一個指針implementation *。該指針是shared_ptr構造函數的參數。這意味着sp1成爲一個智能指針,指向新的implementation對象,這樣當sp1和其後的任何副本都會消失時,對象將被銷燬和刪除。

第二個問題是銷燬實現是由sp1.reset()和sp2.reset()給出的。

事實上,它給出正指向新的價值被破壞雙方sp1sp2的結果。reset做前者,但只是無所作爲,讓他們超出範圍做後者。這是RAII的重要組成部分。

因此,不需要同時調用sp1.reset()和sp2.reset()來釋放shared_ptr,對嗎?

沒錯。你很少想明確地打電話給reset。 RAII的重點在於你不必手動管理這些東西;您初始化一個對象(如shared_ptr)以獲取對資源的訪問權限,並讓該對象消失以釋放訪問權限。

有幾種情況下,它是有用的。例如,如果您有一個shared_ptr作爲對象的成員,並且該對象將持續比它擁有的資源長得多的時間,則可以通過調用reset提前釋放該對象。 (如果您在此期間已將副本傳遞給其他人,則不必擔心其被早期刪除 - 這僅表示您不再參與保持活動狀態。)

1

正如評論中指出的那樣,從SO格式中學習一些基礎知識。

然而,最後一個問題值得回答:

所以沒有必要調用都sp1.reset()和sp2.reset()來釋放shared_ptr的,對嗎?

你看,如果你僅重置您的指針之一實施破壞的原因是由於範圍結束,即從test()返回 - 使你的shared_ptr s到走出去的範圍和被破壞,從而導致銷燬管理對象。

+0

否,它是_not_「程序結束」,它是「範圍末端'sp1'和'sp2'被定義在',這是'test'函數。如果'shared_ptr'沒有刪除對象直到程序結束,那麼對它們的指向會少得多,因爲當程序結束時所有的內存都會被釋放。 (當然,這是「少點」,而不是「沒有意義」,因爲有時析構函數不僅僅是空閒的內存。) – abarnert

+0

@abarnert是的,你當然是對的。修復它。 – SomeWittyUsername