程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++11之智能指針,11智能指針

c++11之智能指針,11智能指針

編輯:C++入門知識

c++11之智能指針,11智能指針


本文介紹c++的四種智能指針,其中後三種是c++11新增加的,auto _ptr已被棄用。

要編譯c++11,需要安裝g++-4.8

sudo add-apt-repository ppa:ubuntu-toolchain-r/test

sudo apt-get update

sudo apt-get instal gcc-4.8

sudo apt-get install g++-4.8

編譯時指定標准:

g++-4.8 -std=c++11

 

auto_ptr詳細請參考這裡

auto_ptr是為了推動RAII而加入到c++標准的第一個智能指針,它實現了最基本的資源管理,不過與其他類型不同的是,auto_ptr是沒有復制語義的,它在復制時實現的其實是移動語義,復制和賦值auto_ptr時會默認改變所管理資源的所有權,基於這個原因,它也不能在stl容器中使用,因為容器內的元素必需支持可復制和可賦值。另外還有一個限制它使用范圍的因素是它的析構函數默認調用delete,而且無法重載,所以不能支持數組等對象。

復制代碼
class A{
public:
    A(int i) :ival(i){
        printf("create  %d \n",ival);   
    }   
    ~A(){
        printf("delete %d \n", ival);   
    }   

    int getvalue(){ return ival;}
private:
    int ival;
};
auto_ptr<A> ptr1(new A(1));
auto_ptr<A> ptr2(new A(2));
assert(ptr1->getvalue()==1);
assert(ptr2->getvalue()==2);
ptr1 = ptr2;
assert(ptr2.get ()==NULL); // now ptr2 is NULL
復制代碼

 

unique_ptr詳細請參考這裡

由於auto_ptr存在各種問題,c++11中unique_ptr華麗登場替換了auto_ptr,它們所做的事情基本一樣,不過unique_ptr不支持復制語義,只支持移動語義,所以無法執行普通的復制或賦值操作(返回將要被銷毀的unique_ptr時例外),但是可以進行移動構造賦值操作,說白了就是復制的話需要顯示move。另外unique_ptr可以重載刪除器,使其支持數組等類型。

復制代碼
unique_ptr<A> ptr1(new A(1));
unique_ptr<A> ptr2(new A(2));
ptr1 = ptr2; //error
ptr1 = move(ptr2); //right, ptr2 is NULL
assert(ptr2==NULL)
unique_ptr<A[]> ptr3(new A[2]{3,4}); //array
assert(ptr3[0].getvalue()==3);
assert(ptr3[1].getvalue()==4);
復制代碼

 

shared_ptr 詳細請參考這裡

通常概念下的智能指針指的是shared_ptr,它允許共享資源,使用引用計數記錄資源被幾個指針共享。調用release(),析構函數或者被復制賦值時,原來管理的資源的引用計數都會減1,計數為0時釋放資源。

復制代碼
shared_ptr<A> ptr1(new A(1));
shared_ptr<A> ptr2(new A(2));
assert(ptr1->getvalue()==1);
assert(ptr1.use_count()==1);
assert(ptr2->getvalue()==2);
assert( ptr2.use_count())==1);
ptr1 = ptr2;
assert(ptr1.use_count()==2)
assert(ptr2.use_count()==2)
assert(ptr1->getvalue()==2);
assert(ptr2->getvalue()==2);
復制代碼

 

weak_ptr詳細請參考這裡

使用shared相互引用時會出現資源無法釋放的情況,比如:

復制代碼
class B;
class A
{
public:
    shared_ptr<B> pb_value;
    ~A()
    {   
        cout<<"A delete\n";
    }   
};
class B
{
public:
    shared_ptr<A> pa_value;
    ~B()
    {   
        cout<<"B delete\n";
    }   
};
shared_ptr<B> pb(new B());
shared_ptr<A> pa(new A());
pb->pa_value = pa;
pa->pb_value = pb;
assert(pa.use_count()==2)
assert(pb.use_count()==2)
復制代碼

引用如下

智能指針

當pa,pb析構後,引用計數都等於1,資源不會釋放。解決方法是將pa_value和pb_value中任意一個聲明為 weak_ptr類型。

week_ptr是對對象的一種弱引用,它不會增加對象的引用計數。week_ptr和shared_ptr之間可以相互轉換,shared_ptr可以直接賦值給week_ptr,week_ptr可通過調用lock函數來獲得shared_ptr(如果對象已經被釋放,則返回一個空的shared_ptr)。

weak_ptr<A> pa_value;

修改後pb->pa_value=pa 不會增加pa的計數,pa計數為1,離開作用域後計數為0,pa正常釋放,於是pb計數也會減為0,正常釋放。


作者:coderkian 
出處:http://www.cnblogs.com/coderkian/ 
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved