智能指針之共享指針


智能指針是存儲指向動態分配對象指針的類。三種智能指針: std::shared_ptr/ std::unique_ptr/ std::weak_ptr.
使用時需要加上頭文件 #include<memory>
1.共享智能指針--shared_ptr
  初始化
    shared_ptr初始化可以通過reset方法初始化shared_ptr。
std::shared_ptr<int> p(new int(1));
std::shared_ptr<int> p2 = p;    //p和p2共享同一段內存
std::shared_ptr<int> ptr;
ptr.reset(new int(1));
int *p1 = new int[2];
std::shared_ptr<int> p3(p1);
if(ptr)
{
   cout << "ptr is not null";
}

另外還可以通過std::make_shared<T>輔助函數初始化,盡量使用std::make_shared<T>初始化共享指針,

auto p1 = std::make_shared<int>(10);
auto p2 = std::make_shared<string>(10,"s");

  可以通過重載的bool類型操作符判斷智能指針是否為空,即是否未初始化。

if(bool(ptr))
    cout << "the ptr is nullptr"<<endl;
else
    cout << "the ptr is not nullptr"<<endl;

 

  --獲取原始指針
      用get()方法獲取原始指針,如:
std::shared_ptr<int> ptr(new int(1));
int *p = ptr.get();

--指定刪除器

    void deleteIntPtr(int* p)
    {
        delete p;
    }
    std::shared_ptr<int> p5(new int,deleteIntPtr);

   或者使用lambda表達式

std::shared_ptr<int> p6(new int,[](int* p){delete p;});

 //管理動態數組時,需要指定刪除器,shared_ptr默認的刪除器不支持數組對象

std::shared_ptr<int> p6(new int[10],[](int* p){delete[] p;});

  //或者使用std::default_delete作為刪除器 

 std::shared_ptr<int> p7(new int[10],std::default_delete<int[]>);

 //此外還可以通過封裝方法讓shared_ptr支持數組    

    template<typename T>
    std::shared_ptr<T> make_shared_array(size_t size)
    {
        return std::shared_ptr<T>(new T[size],std::default_delete<T[]>());
    }
    std::shared_ptr<int> p8 = make_shared_array<int>(10);
    std::shared_ptr<char> p9 = make_shared_array<char>(10);

 使用shared_ptr注意事項

    1.不能使用原始指針初始化多個shared_ptr
   
 int* p11 = new int;
    std::shared_ptr<int> p12(p11);
    std::shared_ptr<int> p13(p11);

 2.不要在實參中創建shared_ptr,應該先創建一個智能指針,再使用

    deleteIntPtr(std::shared_ptr<int>(new int));//錯誤的
    std::shared_ptr<int> p14(new int());
    deleteIntPtr(p14);//OK

3.要通過shared_from_this()返回this指針

struct A
{
    std::shared_ptr<A> getSelf()
    {
        return std::shared_ptr<A>(this);//錯誤,
    }
};
int main()
{ std::shared_ptr
<A> sp1(new A); std::shared_ptr<A> sp2 = sp1->getSelf();//會導致重復析構
   return 0;
}

  采用如下方式,使用enable_shared_from_this類的shared_from_this()方法返回this指針:

class A:public std::enable_shared_from_this
{
public:
    std::shared_ptr<A> getSelf()
    {
        return shared_from_this();
    }
};

4.避免循環使用,如下A/B兩個指針都不會被刪除會有內存泄漏

 

struct A;
struct B;
struct A
{
    std::shared_ptr<B> bptr;
    ~A(){cout << "A is deleted!"<<endl;}
};
struct B
{
    std::shared_ptr<A> aptr;
    ~B() {cout << "B is deleted!"<<endl;}
};
int main()
{
    {
        std::shared_ptr<A> ap(new A);
        std::shared_ptr<B> bp(new B);
        ap->bptr = bp;
        bp->aptr = ap;
    
     }
}

 

  

 

可以將A或B的任何一個shared_ptr成員改為weak_ptr。

 

 

參考:《深入應用C++1:代碼優化與工程級應用》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM