博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++Primer :第十二章:shared_ptr和new的结合使用
阅读量:2435 次
发布时间:2019-05-10

本文共 1958 字,大约阅读时间需要 6 分钟。

shared_ptr和new的结合使用

如果我们不初始化一个智能指针,它就会被初始化为一个空指针,我们可以用new返回的指针来初始化智能指针
接受指针参数的智能指针构造函数是explicit的。因此,我们不能将一个内置指针隐式转化为一个智能指针,必须使用直接初始化形式来初始化为一个智能指针

shared_ptr
p1 = new int(1024); //错误:必须使用直接初始化形式shared_ptr
p2(new int(1024)); //正确,使用了直接初始化形式

p1的初始化隐式地要求用一个new返回的int*来创建一个shared_ptr。由于我们不能进行内置指针到智能指针的隐式转化,因此这条初始化语句是错误的。由于相同的原因,一个返回shared_ptr的函数不能在其返回语句中隐式转化一个普通的指针:

shared_ptr
clone(int p){
return new int(p); //错误:试图隐式转化为shared_ptr
}

我们必须将shared_ptr显式地绑定到一个想要返回的指针上:

shared_ptr
clone(int p){
//显式用int*创建shared_ptr
return shared_ptr
(new int(p));}

定义和改变shared_ptr的其他方法

shared_ptr
p(q); //p管理内置指针q所指的对象;q必须指向new分配的内存,且能够转化为T*类型shared_ptr
p(u); //p从unique_ptr u那里接管了对象的所有权,将u置空shared_ptr
p(q, d); //p将使用可调用对象d来代替deletep.reset(); //若p是唯一指向其对象的shared_ptr,reset会释放此对象p.reset(q); //若传递了可选的参数内置指针q,会令p指向q,否则会将p置空p.reset(q, d);

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

void process(shared_ptr
ptr){
//使用ptr} //ptr离开作用域被销毁
int *x(new int(1024));   //危险:x是一个普通指针,而不是一个智能指针process(x);    //错误:不能将int*转化为一个shared_ptr
process(shared_ptr
(x)); //合法:但内存会被释放int j = *x; //未定义的,x为一个空悬指针

上面的调用中,我们将一个临时shared_ptr传递给process。当这个调用表达式结束时,这个临时对象也就被销毁了。引用计数递减为0,所指向的内存会被释放。

shared_ptr
x(new int(1024));process(x); //拷贝x会递增它的引用计数,在process中引用计数值为2int j = *x; //正确:引用计数值为1

使用一个内置指针来访问一个智能指针所负责的对象是很危险的,因为我们无法知道对象何时会被销毁。

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

智能指针定义了一个名为get的函数,它返回一个内置指针,指向智能指针管理的对象。此函数为下面一种情况所设计的:我们需要向不能使用智能指针的代码传递一个内置指针。使用get返回的指针的代码不能delete此指针。

shared_ptr
p(new int(42)); //引用计数为1int *q = p.get(); //正确,但不要让q所管理的内存释放{
//新的程序块 //未定义:两个独立的shared_ptr指向相同的内存 shared_ptr
(q);} //程序块结束,q被销毁,它指向的内存被释放int foo = *p; //未定义:P指向的内存被释放了

当我们使用p时会发生未定义的行为,而且当p销毁时,这块内存会被第二次delete

get用来将指针的访问权限传递给代码,你只有在确定不会delete指针的情况下,才能使用get。特别是,永远不要get初始化另一个智能指针或者为另一个指针指针赋值。

转载地址:http://btxmb.baihongyu.com/

你可能感兴趣的文章
第七章-面向对象技术
查看>>
Mybatis-略识之无
查看>>
ionic 前端 - 汉字转拼音
查看>>
Ionic-与时间有关的故事-localecompare()
查看>>
Logback-spring.xml日志配置
查看>>
[Vue warn]: Property or method "name" is not defined on the instance but referenced during render
查看>>
ts:json串转换成数组
查看>>
String、StringBuffer和StringBuilder的区别
查看>>
java——职责链模式
查看>>
java_选择类排序——简单选择排序
查看>>
java_中介者模式
查看>>
java_备忘录模式
查看>>
多线程——背景了解
查看>>
power designer使Comment与Name相同.txt
查看>>
学习Spring 开发指南------基础语义
查看>>
IE下的图片空隙间距BUG和解决办法
查看>>
[pb]从excel导入数据到datawindow
查看>>
CSS Padding in Outlook 2007 and 2010
查看>>
有关内存的思考题
查看>>
What is the difference between gross sales and revenue?
查看>>