智能指针

智能指针就是类,当超出了类的作用域,类会自动调用析构函数,析构函数释放资源,就不需要再手动释放资源了。

1、auto_ptr(cpp11抛弃)

所有权模式;

1 auto_ptr< string> p1 (new string ("I reigned lonely as a cloud.”));
2 auto_ptr<string> p2;
3 p2 = p1; //auto_ptr不会报错.

当p1指针赋值给了p2,相当于这块内存的所有权给了p2,在访问p1就会报错。

缺点:内存崩溃问题。

auto_ptr操作

1 auto_ptr<int> p1;//创建一个空指针
2 
3 auto_ptr<int> p1;
4 double* p2 = new double;
5 p1 = auto_ptr<int>(p2);//将p2赋给p1,不能将智能指针赋给非智能指针,智能指针之间可以相互赋值
6 
7 double* p2 = new double;
8 autp_ptr<int> p1(p2);

2、unique_ptr

替换auto_ptr;

独占式拥有,同一时间只能有一个智能指针可以指向对象。

解决了忘了delete造成的内存泄漏问题。

不可以将一个unique_ptr指针赋值给另一个unique_ptr指针,除非源unique_ptr是个临时右值。

unique_ptr<string> pu1(new string ("hello world"));
unique_ptr<string> pu2;
pu2 = pu1;                                      // #1 not allowed
unique_ptr<string> pu3;
pu3 = unique_ptr<string>(new string ("You"));   // #2 allowed

或者使用std::move,将一个unique_ptr赋给另外一个:

unique_ptr<string> ps1, ps2;
ps1 = demo("hello");
ps2 = move(ps1);
ps1 = demo("alexia");
cout << *ps2 << *ps1 << endl;

unique_ptr基本操作

 1 //创建空智能指针
 2 unique_ptr<int> u_i; 
 3 
 4 //"绑定”动态对象 
 5 u_i.reset(new int(3)); 
 6 
 7 //创建时指定动态对象 
 8 unique_ptr<int> u_i2(new int(4));
 9 
10 //创建空unique_ptr,执行类型为T的对象,用类型为D的对象d来替代默认的删除器delete
11 unique_ptr<T,D> u(d);    
12 
13 //所有权的变化  
14 int *p_i = u_i2.release(); //释放所有权  
15 unique_ptr<string> u_s(new string("abc"));  
16 unique_ptr<string> u_s2 = std::move(u_s); //所有权转移(通过移动语义),u_s所有权转移后,变成“空指针” 
17 u_s2.reset(u_s.release());//所有权转移
18 u_s2=nullptr;//显式销毁所指对象,同时智能指针变为空指针。与u_s2.reset()等价
1 unique_ptr<type> u1;
2 unique_ptr<T,D> u2;释放它的指针,u2会使用一个类型为d的可调用对象来释放它的指针
3 unique_ptr<T,D> u(d);空unique_ptr,指向类型为T的对象,用类型为D的对象代替delete
4 u=nullptr;释放u指向的对象,并将u置空
5 u.release();u放弃对指针的控制权,返回指针,并将u置空
6 u.reset() 释放u指向的对象
7 u.reset(q);如果提供了内置指针q,令u指向这个对象,否则将u置空
8 u.reset(nullptr)

3、shared_ptr

解决auto_ptr只能独占对象的问题,可以共享所有权的智能指针。

多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。

成员函数:

use_count 返回引用计数的个数

unique 返回是否是独占所有权( use_count 为 1)

swap 交换两个 shared_ptr 对象(即交换所拥有的对象)

reset 放弃内部对象的所有权或拥有对象的变更, 会引起原有对象的引用计数的减少

get 返回内部对象(指针), 由于已经重载了()方法, 因此和直接使用对象是一样的.如 shared_ptr<int> sp(new int(1)); sp 与 sp.get()是等价的

//shared_ptr和unique_ptr都支持的对象
unique_ptr<type> up;
p; //将p用作一个条件判断,若p指向一个对象,则为true
*p;//解引用,获得指向的对象
p.get();//返回p中保存的指针。若智能指针释放了其对象,返回的指针所指向的对象也就消失了
swap(p,q);//交换p和q中的指针
p.swap(q)

4、weak_ptr

为了配合shared_ptr指针的工作引入的。

如果两个shared_ptr指针相互引用时,那么这两个指针的引用计数永远不可能下降到0,产生死锁问题。

weak_ptr是一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr。

不能通过weak_ptr直接访问对象的方法,应该先把它转化为shared_ptr。

weak_ptr的构造函数不会修改引用计数的值,从而不会对对象的内存进行管理,其类似一个普通指针,但不指向引用计数的共享内存,但是其可以检测到所管理的对象是否已经被释放,从而避免非法访问。

1 weak_ptr<T> w;         //创建空weak_ptr,可以指向类型为T的对象。
2 weak_ptr<T> w(sp);    //与shared_ptr指向相同的对象,shared_ptr引用计数不变。T必须能转换为sp指向的类型。
3 w=p;                //p可以是shared_ptr或weak_ptr,赋值后w与p共享对象。
4 w.reset();            //将w置空。
5 w.use_count();        //返回与w共享对象的shared_ptr的数量。
6 w.expired();        //若w.use_count()为0,返回true,否则返回false。
7 w.lock();            //如果expired()为true,返回一个空shared_ptr,否则返回非空shared_ptr。

 

posted @ 2019-07-18 20:44  Austin_anheqiao  阅读(246)  评论(0编辑  收藏  举报