c++智能指针

静态内存和栈内存。静态内存用来保存局部的static对象、类的static数据成员以及定义在任何函数之外的变量。栈内存用来保存定义在函数内的非static的对象。分配在静态或者栈内存中的对象由编译器自动创建和销毁。
对于栈对象,仅在其定义的程序运行时才存在;static对象在使用之前分配,在程序结束时销毁。
除了静态内存和栈内存之外,每个程序还拥有一个内存池。这部分内存被称作自由空间或堆。程序用堆来存储动态分配的对象-即那些在程序运行时分配的对象。动态对象的生存周期由程序来控制,也就是程序不在使用时,我们代码必须显式的销毁它。
但是动态对象的正确释放被证明是编程中极其容易出错的地方。为了更安全地使用动态对象,标准库定义了两个智能指针类型来动态管理动态分配的对象。当一个对象应该被释放时,指向它的智能指针可以确保自动的释放它。
动态内存的管理是通过一对运算符号来完成的:new,在动态内存中为对象分配内存空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化;delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。

为了更容易的使用动态内存,新的标准提出两种智能指针:重要的区别是它负责自动释放所指向的对象。
shared_ptr:允许多个指针指向同一个对象;
unique_ptr则独占所指向的对象。
标准库还定义了一个名为weak_ptr的伴随类,它是一个弱引用,指向shared_ptr所管理的对象。这三个类型都定义在memory头文件中。

share_ptr p1; //shared_ptr,可以指向string
shared_ptr<list> p2; // shared_ptr,可以指向int的list

默认初始化的智能指针中保存着一个空指针。
智能指针的使用方式与普通指针类似。解引用一个智能指针返回指向的对象。如果一个条件判断中使用智能指针,效果就是检测它是否为空。

if(p1&&p1->empty())  //如果p1不为空,检测它是否指向一个空的string
*p1 = "hi";                    //如果p1指向一个空的string,解引用p1,将一个新值赋予string
share_ptr和unique_ptr都支持的操作

share_ptr<T> sp 空智能指针,可以指向类型为T的对象
unique_ptr<T> up
p                      将用作一个判断条件,若p指向一个对象,则为true
*p                     解引用p,获得它指向的对象
p->mem                 等价于(*p).mem
p.get()                返回p中保存的指针。要小心使用,若智能指针释放其对象,返回的指针指向的对象也就消失。
swap(p, q)             交换p和q中的指针
p.swap(q)
make_share<T> (args) 返回一个share_ptr,指向一个动态分配的类型为T的对象。使用args初始化此对象
share_ptr<T>p (q) p是share_ptr q的拷贝;此操作会递增q中的计数器,q中的指针必须能转换为T*
p=q p和q都是share_ptr,所保存的指针必须能相互转换。此操作会递减p的引用计数,递增q的引用计数;若p的引用计数变为0,则将其管理的原内存释放。
p.unique() 若p.use_count()为1,返回true;否则返回false。
p.use_count() 返回与p共享对象的智能指针数量;可能很慢,主要用于调试。

make_share函数
最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数。此函数在动态内存中分配一个对象并初始化它,返回指向此对象的share_ptr。与智能指针一样,make_shared也定义在头文件memory中。
make_share T参数必须与T的某个构造函数匹配,如下
//指向一个值为42的int的share_ptr
share_ptr p3 = make_share (42);
//指向一个值为"999999999"的string
share_ptr p4 = make_share (10, 9);
使用auto定义一个对象来保存make_shared的结果
auto p6 = make_shared<vector>();
share_ptr的拷贝和赋值
当进行拷贝或者赋值操作时,每个share_ptr都会记录有多少个其他share_ptr指向相同的对象:
auto p = make_share (42);//p指向的对象只有p一个引用者
auto q§;//p和q指向相同对象,此对象有两个引用者。
我们可以认为每个share_ptr都有一个关联的计数器,通常称其为引用计数(reference count)。无论何时我们拷贝一个share_ptr,计数器都会递增。
例如:当用一个share_ptr初始化另一个share_ptr,或将它作为参数传递给一个函数以及作为函数的返回值时,它所关联的计数器就会递增。当我们给share_ptr赋予一个新值或是share_ptr被销毁(例如一个局部的share_ptr离开其作用域时,计数器就会递减)。
一旦一个share_ptr的计数器变为0,它就会自动释放管理的对象:
auto r = make_share (42)//r指向的int只有一个引用值
r = q;//给r赋值,令它指向另一个地址
//递增q指向的对象的引用计数
//递减r的引用计数
//r原来指向的对象已经没有引用者,会自动释放。
此例中我们分配了一个int,将其指针保存在r中。接下来,我们将一个新值赋予r。在此情况下,r是唯一指向该int的share_ptr,在把q赋给r的过程中,此int自动释放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值