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