C++学习——动态内存与智能指针

动态内存与智能指针

动态内存的管理是通过一对运算符来完成:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,可以选择对对象进行初始化:delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。

为了更容易(同时也更安全)地使用动态内存,新的标准库提供了两种智能指针类型来管理动态对象。

智能指针与常规指针的区别是它负责自动释放所指向的对象。

新标准库提供的这两种智能指针的区别在于管理底层指针的方式:

  • shared_ptr 允许多个指针指向同一个对象;
  • unique_ptr 则“独占”所指向的对象。

还定义了一个名为 weak_ptr 的伴随类,它是一种弱引用,指向 shared_ptr 所管理的对象。
这三种类型都定义在 memory 头文件中。

shared_ptr 类

智能指针也是模板。

当创建一个智能指针时,必须提供额外的信息——指针可以指向的类型。
在尖括号内给出类型,之后是所定义的这种智能指针的名字:

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

默认初始化的智能指针中保存着一个空指针。

智能指针的使用方式与普通指针类似。解引用一个智能指针返回它指向的对象。

如果有一个条件判断中使用智能指针,效果就是检测它是否为空:

// 如果p1不为空,检查它是否指向一个空 string 
if (p1 && P1->empty())
	*p1 = "hi";   // 如果p1指向一个空 string,解引用p1,将一个新值赋予 string

在这里插入图片描述

make_shared 函数

最安全的分配和使用动态内存的方法。

此函数在动态内存中分配一个对象并初始化它,返回指向此对象的 shared_ptr。
与智能指针一样,make_shared 也定义在头文件 memory 中。

当要用 make_shared 时,必须指定想要创建的对象的类型。
定义方式与模板类相同,在函数名之后跟一个尖括号,在其中给出类型:

// 指向一个值为42的int的shared_ptr
shared_ptr<int> p3 = make_shared<int>(42);
// p4指向一个值为“9999999999”的string
shared_ptr<string> p4 = make_shared<string>(10, '9');
//p5指向一个值初始化的 int,即,值为0
shared_ptr<int> p5 = make_shared<int>();

通常用 auto 定义了一个对象来保存 make_shared 的结果,这种方式较为简单:

// p6 指向一个动态分配的空 vactor<string>
auto p6 = make_shared<vector<string>>();

shared_ptr 的拷贝和赋值

当进行拷贝或赋值操作时,每个 shared_ptr 都会记录有多少个其他 shared_ptr 指向相同的对象:

auto p = make_shared<int>(42); //p指向的对象只有p一个引用者
auto q(p);  // p 和 q指向相同对象,此对象有两个引用者

每个 shared_ptr 都有一个关联的计数器,通常称其为引用计数

无论何时拷贝一个 shared_ptr ,计数器都会增加。
当给 shared_ptr 赋予一个新值或是 shared_ptr 被销毁时,计数器就会递减。

一旦一个 shared_ptr 的计数器变为0,它就会自动释放自己所管理的对象:

auto r = make_shared<int>(42);  // r指向的 int 只有一个引用者
r = q; // 给 r 赋值,令它执行另一个地址
 	   // 递增q指向的对象的引用计数
  	   // 递减r原来指向的对象的引用计数	  
  	   // r 原来指向的对象已没有引用者,会自动释放 

shared_ptr 自动销毁所管理的对象……

当指向一个对象的最后一个 shared_ptr 被销毁时,shared_ptr 类会自动销毁此对象。
它通过另一个特殊的成员函数——析构函数完成销毁工作。

析构函数一般用来释放对象所分配的资源。

shared_ptr 的析构函数会递减它所指向的对象的引用计数。如果引用计数变为0,shared_ptr 的析构函数就会销毁对象,并释放它占用的内存。

…… shared_ptr 还会自动释放相关联的内存

当动态对象不再被使用时,shared_ptr 类会自动释放动态对象,这一特性使得动态内存的使用变得非常容易。

使用了动态生存期的资

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值