Boost庫中的智能指針 shared_ptr智能指針

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<exampleexampleTwo = exampleOne;

時擁有了example對象的訪問權限

exampleOneexampleTwo都釋放對該對象的所有權時,

exampleOne.reset();

exampleTwo.reset();

其所管理的的對象的內存才被自動釋放。在共享對象的訪問權限同時,也實現了其內存的自動管理。

boost::shared_ptr的內存管理機制:

究其本質boost::shared_ptr的管理機制其實並不複雜,就是對所管理的對象進行了引用計數,當新增一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數加一;減少一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數減一,如果該對象的引用計數爲0的時候,說明沒有任何指針對其管理,才調用delete釋放其所佔的內存。

上面的那個例子可以的圖示如下:

  1. exampleOne對example對象進行管理,其引用計數爲1 
  2. 增加exampleTwoexample對象進行管理,其引用計數增加爲2 
  3. exampleOne釋放對example對象進行管理,其引用計數變爲1 
  4. exampleTwo釋放對example對象進行管理,其引用計數變爲0,該對象被自動刪除 

boost::shared_ptr的特點:

boost::shared_ptr可以共享對象的所有權,因此其使用範圍基本上沒有什麼限制(還是有一些需要遵循的使用規則,下文中介紹),自然也可以使用在stl的容器中。另外它還是線程安全的,這點在多線程程序中也非常重要。

boost::shared_ptr的使用規則:

boost::shared_ptr並不是絕對安全,下面幾條規則能使我們更加安全的使用boost::shared_ptr:

  1. 避免對shared_ptr所管理的對象的直接內存管理操作,以免造成該對象的重釋放
  2. shared_ptr並不能對循環引用的對象內存自動管理(這點是其它各種引用計數管理內存方式的通病)。
  3. 不要構造一個臨時的shared_ptr作爲函數的參數。
    如下列代碼則可能導致內存泄漏:
    void test()
    {
        test1(boost::shared_ptr<example>(new    example()),g());
    }
    正確的用法

    void test()
    {
        boost::shared_ptr<example> sp    (new example());
        test1(sp,g());
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章