智能指针是一个RAII类模型,用于动态分配内存,其设计思想是将基本类型指针封装为(模板)类对象指针,并在离开作用域时调用析构函数,使用delete
删除指针所指向的内存空间。
在C++中,动态内存的管理是用一对运算符完成的:new和delete,new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针,delete:指向一个动态独享的指针,销毁对象,并释放与之关联的内存。
动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针。
为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。 智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。 标准库提供的两种智能指针的区别在于管理底层指针的方法不同,shared_ptr允许多个指针指向同一个对象,unique_ptr则“独占”所指向的对象。 标准库还定义了一种名为weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,这三种智能指针都定义在memory头文件中。
shared_ptr类
对于shared_ptr
,实现共享式拥有的概念,即多个智能指针可以指向相同的对象,该对象及相关资源会在其所指对象不再使用之后,自动释放与对象相关的资源;
make_shared函数: 头文件和share_ptr相同,在memory中
最安全的分配和使用动态内存的方法就是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr。
必须指定想要创建对象的类型,定义格式见下面例子:
shared_ptr p3 = make_shared(42);
shared_ptr p4 = make_shared(10,'9');
shared_ptr p5 = make_shared();
make_shared用其参数来构造给定类型的对象,如果我们不传递任何参数,对象就会进行值初始化
shared_ptr的拷贝和赋值
当进行拷贝和赋值时,每个shared_ptr都会记录有多少个其他shared_ptr指向相同的对象。
auto p = make_shared(42);
auto q(p);
下表为定义和改变shared_ptr的其他方法:
weak_ptr类
解决shared_ptr
相互引用时,两个指针的引用计数永远不会下降为0,从而导致死锁问题。
而weak_ptr
是对对象的一种弱引用,可以绑定到shared_ptr
,但不会增加对象的引用计数。
unique_ptr类
实现独占式拥有的概念,同一时间只能有一个智能指针可以指向该对象,因为无法进行拷贝构造和拷贝赋值,但是可以进行移动构造和移动赋值;
下表是unique的 *** 作:
虽然我们不能拷贝或者赋值unique_ptr,但是可以通过调用release或reset将指针所有权从一个(非const)unique_ptr转移给另一个unique
//将所有权从p1(指向string Stegosaurus)转移给p2
unique_ptr p2(p1.release());//release将p1置为空
unique_ptrp3(new string("Trex"));
//将所有权从p3转移到p2
p2.reset(p3.release());//reset释放了p2原来指向的内存
auto_ptr类
- 实现独占式拥有的概念,同一时间只能有一个智能指针可以指向该对象;但
auto_ptr
在C++11中被摒弃,其主要问题在于:
- 对象所有权的转移,比如在函数传参过程中,对象所有权不会返还,从而存在潜在的内存崩溃问题;
- 不能指向数组,也不能作为STL容器的成员。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)