C++リソース管理(RAII)--スマートポインタ

32827 ワード

1.スマートポインタ(Smart Pointer)
i.動的割当て(スタック)オブジェクトへのポインタを格納するクラス
          ii.動的に割り当てられたオブジェクトを正しく破棄できるため、例外に直面した場合に特に役立ちます.
iii.RAII類アナログ知能ポインタ、備考を参照
2.C++11は、テンプレートクラスであるヘッダファイルに位置する次のスマートポインタを提供します.
          i. std::auto_ptr(コピー/付与)
          ii. std::unique_ptr  c++11
          iii.std::shared_ptr  c++11
          iv.std::weak_ptr    c++11
          g++ -std=c++11 xx.cc
3. std::auto_ptrは、構築時にオブジェクトの所有権(ownership)を取得し、構築時にオブジェクトを解放する
4. std::auto_ptrは、「裸」ポインタの完全な占有性を要求する->コピー構造または付与操作時に所有権の移行が発生する
5.自身に欠陥がある
6. std::unique_ptrは、所有権を独占するインテリジェントなポインタであり、以下のような厳格な意味での所有権を提供します.
i.指向するオブジェクトを持つ
           ii.レプリケーション、割り当て操作ができません(例題)
iii.あるオブジェクトへのポインタを保存し、それ自体が削除されて解放されると、指定された削除器を使用してそのオブジェクトを解放します.
iv.移動(std::move)の意味を持ち、コンテナ要素とすることができる
7. std::shared_ptrは、オブジェクトの所有権を共有するための参照カウントスマートポインタです.
i.カウンタshared_を導入しましたcountは、現在何個のスマートポインタオブジェクトがポインタを共有しているかを示すメモリブロックです.
           ii.解析関数ではポインタを直接解放するメモリブロックではありません.shared_countが0より大きい場合はメモリを解放しない参照カウントを1減少させるだけで、カウントが0に等しい場合はメモリを解放する
iii.レプリケーション構造と付与オペレータは、一般的なレプリケーション機能を提供するだけで、参照カウントを1加算.
iv.スタックメモリには申請されたリソースが1つしかありませんが、このメモリのリソースを指すオブジェクトはいくつかあります.
           v. Shared_ptrの機能は,値の意味を持たないオブジェクトに値の意味を持たせることであり,1つのオブジェクト自体が複製されたくないといえば,shared_に渡す.ptr管理の場合、このポインタを使用するとオブジェクトをコピーできますが、実際には実際のオブジェクトのコピーではなく、参照カウントで使用します.
8.問題:循環参照でメモリが漏れるという問題があります.
9. std::shared_ptrは強力なリファレンススマートポインタです
10. std::weak_ptrは弱いリファレンススマートポインタです
11.強い参照、1つの参照が存在する限り、オブジェクトは解放されません
12.弱い参照は、オブジェクトの参照数を増やすことはありませんが、オブジェクトが存在するかどうかを知っています.存在する場合はshared_に昇格ptr成功;そうでなければ、昇格に失敗します
13.weak経由ptrがオブジェクトのメンバーにアクセスするときはshared_に昇格するptr
 
 1 auto_ptr.cc  2 

 3 #include<iostream>

 4 #include<memory>

 5 

 6 int main(void)

 7 {

 8     double *pd = new double(7.77);

 9     std::auto_ptr<double> apd(pd);  //apd      ,             ,     *  。

10     //  std::auto_ptr<double> apd(new double(7.77));

11 

12     std::cout << “*apd=” << *apd <<std::endl;

13     //  *       ,            (pd)           .

14     

15     //std::cout << “apd = ” << apd << std::endl;  //

16     

17     std::cout << “apd.get() = ” << reinterpret_cast<long>(apd.get()) << std::endl;    

18 

19     double *pd = new double(8.88);

20     std::auto_ptr<double> apd2(pd);  

21     std::cout << “pd = ” << reinterpret_cast<long>(pd) << std::endl;

22 std::cout << “apd2.get() = ” << reinterpret_cast<long>(apd2.get()) << std::endl;    //  get()              。

23 

24     int *pi = new int(7);

25     std::auto_ptr<int> api1(pi);

26     std::auto_ptr<int> api2(api1);  //  ,          。   api1           api2,     api1         。   api1 pi         api2。        ,        。     ,     。

27 // std::auto_ptr    “ ”                   ,         

28 

29 std::cout << “*api1= ” << *api1 <<std::endl;  //    api1    ,     ,       。

30     std::cout << “*api2 = ” << *api2 <<std::endl;

31     

32 

33     return 0;

34 }
 1 unique_ptr.cc  2 

 3 #include<iostream>

 4 #include<memory>

 5 #include<vector>

 6 

 7 

 8 std::unique_ptr<int> getVal()   //      unique_ptr  ,        。

 9 { 

10     std::unique_ptr<int> up(new int(66));

11     return up;

12 }

13 

14 int main(void)

15 {

16     //

17     std::unique_ptr<int> ap(new int(99));

18     //std::unique_ptr<int> one(ap);   //    ,       。

19 

20     std::unique_ptr<int> two;

21     //two = ap;  //    ,      。

22 

23     std::cout << “*ap = ” << *ap << std::endl;

24     std::cout << “ap.get() = ” << reinterpret_cast<long>(ap.get())  << std::endl;  //      

25     

26     //               

27     std::unique_ptr<int> up = getVal();   //getVal()        ,                。unique_ptr        ,                          。               。           。

28     std::cout << “*up = ” << *up << std::endl;

29 

30 

31     //                 

32     Unique_ptr<int> up(int new int(99));

33     Unique_ptr<int> uPtr2 = std::move(up);  //           。 up       uPtr2 , up       。

34 

35 

36     

37     //         (          )

38     std::unique_ptr<int> sp(new int(55));  //sp       ,              ,                  。

39     std::vector<std::unique_ptr<int> vec;

40     //vec.push_back(sp);   //

41     vec.puch_back(std::move(sp));  //         ,             ,          。

42     std::cout << *vec[0] << std::endl;  //

43 

44     return 0;

45 }
 1 Shared_ptr.cc  2 

 3     #include<iostream>

 4     #include<memory>

 5     

 6     class Child;

 7     class Parent;

 8 

 9     typedef std::shared_ptr<Child> Child_ptr;

10     typedef std::shared_ptr<Parent> Parent_ptr;

11 

12     class Child

13     {

14     public:

15         Child()

16          {

17             std::cout << “Child()” << std::endl;

18 }

19 ~Child()

20          {

21             std::cout << “~Child()” << std::endl;

22 }

23      //private:    

24         Parent_ptr parent_;

25 };

26     

27     class Parent

28     {

29     public:

30         Parent()

31         {    

32             std::cout << “Parent()” << std::endl;

33 }

34 ~Parent()

35         {    

36             std::cout << “~Parent()” << std::endl;

37 }

38 

39     //private:

40         Child_ptr child_;

41 };

42 

43 int main(void)

44 {

45     Parent_ptr parent(new Parent);  //  shared_ptr    

46     Child_ptr child(new Child);    

47 

48     std::cout << “parent’s count = ”  << parent.use_count() << std::endl;

49     std::cout << “child’s count = ” << child.use_count() << std::endl;

50 

51     std::cout << “      :” << std::endl;

52     parent->child_  = child;      //shared_ptr    

53     std::cout << “child’s count = ” << child.use_count() << std::endl;  //        2.

54     child->parent_ = parent;

55     std::cout << “parent’s count = ”  << parent.use_count() << std::endl;   //        2.

56     

57     return 0;

58 }

59     //      ,      ,       ,   1。             ,         。          ,          。

 
 1 weak_ptr1.cc  2 

 3     #include<iostream>

 4     #include<memory>

 5     

 6     class Child;

 7     class Parent;

 8 

 9     typedef std::shared_ptr<Child> Child_ptr;

10     typedef std::shared_ptr<Parent> Parent_ptr;

11 

12     class Child

13     {

14     public:

15         Child()

16          {

17             std::cout << “Child()” << std::endl;

18 }

19 ~Child()

20          {

21             std::cout << “~Child()” << std::endl;

22 }

23      //private:    

24         Parent_ptr parent_;

25 };

26     

27     class Parent

28     {

29     public:

30         Parent()

31         {    

32             std::cout << “Parent()” << std::endl;

33 }

34 ~Parent()

35         {    

36             std::cout << “~Parent()” << std::endl;

37 }

38     

39 std::weak_ptr<Child> child_;  //   

40 };

41 

42 int main(void)

43 {

44     Parent_ptr parent(new Parent);  //  shared_ptr    

45     Child_ptr child(new Child);    

46 

47     std::cout << “parent’s count = ”  << parent.use_count() << std::endl;

48     std::cout << “child’s count = ” << child.use_count() << std::endl;

49 

50     std::cout << “      :” << std::endl;

51     parent->child_  = child;      //child_ weak_ptr,        1

52     std::cout << “child’s count = ” << child.use_count() << std::endl;  //        2.

53     child->parent_ = parent;

54     std::cout << “parent’s count = ”  << parent.use_count() << std::endl;   //        2.

55     

56     return 0;

57 }

58     //         ,            1.             。
 1 Weak_ptr.cc
2 #include<iostream> 3 #include<memory> 4 5 class X 6 { 7 public: 8 X() {std::cout << “X()” << std::endl;} 9 ~ X() {std::cout << “~X()” << std::endl;} 10 11 void fun() 12 { 13 std::cout << “fun()” << std::endl; 14 } 15 }; 16 17 int main(void) 18 { 19 std::weak_ptr<X> p; 20 { 21 std::shared_ptr<X> p2(new X); // new p2 , p2 , delete 。 22 std::cout << “p2’s count = ” << p2.use_count() <<std::endl; 23 24 p = p2; //std::weak_ptr 25 std::cout << “after p = p2 ” <<std::endl; 26 std::cout << “p2’s count = ” << p2.use_count() <<std::endl; 27 28 std::shared_ptr<X> p3 = p.lock(); //lock() weak_ptr shared_ptr 。 29 30 if(p3) // 31 { 32 p3->fun(); 33 std::cout << “p3’s count = ” << p3.use_count() <<std::endl; 34 } 35 else // 36 { 37 std::cout << “object has been destroied” << std::endl; 38 } 39 } 40 41 //new X 42 // weak_ptr , shared_ptr 43 std::shared_ptr<X> p4 = p.lock(); 44 if(p4) // 45 { 46 P4->fun(); 47 std::cout << “p4’s count = ” << p4.use_count() <<std::endl; 48 } 49 else // 50 { 51 std::cout << “object has been destroied” << std::endl; 52 } 53 54 // , 。 , 、 。 55 // : , 。 56 //std::shared_ptr<X> *pthis = new std::shared_ptr<X>(new X); 57 // , 。 delete , 。 58 59 return 0; 60 }