第12章 动态内存

12.1 动态内存与智能指针

12.1.1 shared_ptr类

shared_ptr和unique_ptr都支持的操作
shared_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)

 

shared_ptr独有的操作
make_shared<T>(args)返回一个shared_ptr,指向一个动态分配的类型为T的对象,使用args初始化此对象
shared_ptr<T> p(q)p是shared_ptr q的拷贝,此操作会递增q的计数器
p = qp和q都是shared_ptr,所保存的指针必须能相互转换,此操作会递减p的计数器,递增q的计数器
p.unique()若p.use_count()为1返回true,否则返回false
p.use_count()返回与p共享对象的智能指针

1、make_shared函数

shared_ptr<int> p1 = make_shared<int>(42);
shared_ptr<int> p2 = make_shared<int>();     //p2指向一个值初始化的int,即值为0

 2、shared_ptr和new结合使用

  • 接收指针参数的智能指针的构造函数时explicit的,必须使用直接初始化,不支持隐式类型转换
shared_ptr<int> p1(new int(1024)); //正确,使用了直接初始化
shared_ptr<int> p2 = new int(1024);//错误

3、不要混合使用普通指针和智能指针

  • 当将一个shared_ptr绑定到一个普通指针时,就认为将内存管理责任交给shared_ptr了,不应当再使用内置指针访问shared_ptr所指向的对象了

4、不要使用get初始化另一个智能指针或为智能指针赋值

  • get返回一个内置指针,指向智能指针管理的对象,只有在确定代码不会delete该指针的情况下才能使用,因此不能用来初始化另一个智能指针或者为另一个智能指针赋值

5、定义和改变shared_ptr的其他方法

定义和改变shared_ptr的其他方法
shared_ptr<T> p(q)p管理内置指针q所指的对象,q必须时new分配的内存,且能够转换为T *
shared_ptr<T> p(u)p从unique_ptr u那里接管了对象的所有权,将u置空
shared_ptr<T> p(q, d)p管理内置指针q所指的对象,q必须时new分配的内存,且能够转换为T *,p将使用可调用对象d来代替delete
shared_ptr<T> p(p2, d)p是shared_ptr p2的拷贝,并使用可调用对象d来代替delete
p.reset()若p是唯一指向其对象的shared_ptr,reset会释放此对象,若传递了可选的内置指针q,会令p指向q,否则会将p置空。若还传递了参数d,将会调用d而不是delete来释放q
p.reset(q)
p.reset(q, d)

12.1.2 直接管理内存

1、可以对动态分配的对象进行值初始化,只需要在类型名之后增加一对空括号即可

string *ps1 = new string;    //默认初始化为空string
string *ps2 = new string();  //值初始化为空string
int *pi1 = new int;          //默认初始化 *pi1未定义
int *pi2 = new int();        //值初始化为0

12.1.5 unique_ptr类

unique_ptr操作
unique_ptr<T> u1空unique_ptr,u1使用delete来释放它的指针,u2使用一个类型为D的可调用对象来释放它的指针
unique_ptr<T, D> u2 
unique_ptr<T, D> u(d)空unique_ptr,指向类型为T的对象,用类型为D的对象d代替delete
u = nullptr释放u指向的对象
u.release()u放弃对指针的控制权,返回内置类型指针,并将u置空
u.reset()释放u指向的对象
u.reset(q)如果提供了内置类型q,令u指向这个对象,否则将u置空
u.reset(release) 

1、初始化unique_ptr必须采用直接初始化的形式(使用new返回的内置指针),且unique不支持拷贝或赋值操作

2、不能拷贝unique_ptr规则有一个例外,我们可以拷贝或赋值一个将要被销毁的unique_ptr,最常见的就是从函数返回一个unique_ptr

unique_ptr<int> clone(int p) {
    return unique_ptr<int>(new int(p));
}

unique_ptr<int> clone(int p) {
    unique_ptr<int> ret(new int(p));
    return ret;
}

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值