shared_ptr智能指針的意思即:boost::shared_ptr是可以智能的管理動態分配的內存資源,幾個智能指針可以同時共享一個動態分配的內存的所有權。
下面我們通過一個例子來學習一下它的用法:
注 :使用shared_ptr智能指針,要加入#include <boost/shared_ptr.hpp>頭文件
class example
{
public:
~example() { std::cout <<"It's
over\n"; }
void do()
{ std::cout << "well doen\n";
}
};
void testExample()
{
boost::shared_ptr<example>
exampleOne(new example());
std::cout<<"The example
now has "<<exampleOne.use_count()<<"
references\n";
boost::shared_ptr<example>
exampleTwo =
exampleOne;
std::cout<<"The
example now has "<<exampleTwo.use_count()<<"
references\n";
exampleOne.reset();
std::cout<<"After Reset
exampleOne. The example now has "<<exampleTwo.use_count()<<"
references\n";
exampleTwo.reset();
std::cout<<"After Reset
exampleTwo.\n";
}
void main()
{
testExample();
}
該程序的輸出結果如下:
The example now has 1 references
The
example now has 2 references
After Reset
exampleOne. The example now has 1 references
It's over
After Reset
exampleTwo.
到此例子的代碼完畢。我們可以看到,boost::shared_ptr智能指針exampleOne在
boost::shared_ptr<example> exampleOne(new example());
時擁有了example對象的訪問權限
boost::shared_ptr智能指針exampleTwo在
boost::shared_ptr<example> exampleTwo = exampleOne;
時擁有了example對象的訪問權限
當exampleOne和exampleTwo都釋放對該對象的所有權時,
exampleOne.reset();
exampleTwo.reset();
其所管理的的對象的內存才被自動釋放。在共享對象的訪問權限同時,也實現了其內存的自動管理。
boost::shared_ptr的內存管理機制:
究其本質boost::shared_ptr的管理機制其實並不複雜,就是對所管理的對象進行了引用計數,當新增一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數加一;減少一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數減一,如果該對象的引用計數爲0的時候,說明沒有任何指針對其管理,才調用delete釋放其所佔的內存。
上面的那個例子可以的圖示如下:
-
exampleOne對example對象進行管理,其引用計數爲1
-
增加exampleTwo對example對象進行管理,其引用計數增加爲2
-
exampleOne釋放對example對象進行管理,其引用計數變爲1
-
exampleTwo釋放對example對象進行管理,其引用計數變爲0,該對象被自動刪除
boost::shared_ptr的特點:
boost::shared_ptr可以共享對象的所有權,因此其使用範圍基本上沒有什麼限制(還是有一些需要遵循的使用規則,下文中介紹),自然也可以使用在stl的容器中。另外它還是線程安全的,這點在多線程程序中也非常重要。
boost::shared_ptr的使用規則:
boost::shared_ptr並不是絕對安全,下面幾條規則能使我們更加安全的使用boost::shared_ptr:
-
避免對shared_ptr所管理的對象的直接內存管理操作,以免造成該對象的重釋放
-
shared_ptr並不能對循環引用的對象內存自動管理(這點是其它各種引用計數管理內存方式的通病)。
-
不要構造一個臨時的shared_ptr作爲函數的參數。
如下列代碼則可能導致內存泄漏:
void test()
{
test1(boost::shared_ptr<example>(new example()),g());
}
正確的用法爲:
void test()
{
boost::shared_ptr<example> sp (new example());
test1(sp,g());
}