博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++Primer : 第十二章 :智能指针和异常
阅读量:2434 次
发布时间:2019-05-10

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

智能指针和异常

即时程序块过早结束,智能指针类也能确保在内存不再需要时将其释放

void f(){
shared_ptr
sp(new int(42)); //分配一个新对象 //这段代码抛出一个异常,且在f中未被捕获} //在函数结束时shared_ptr自动释放内存

与之对应的,当发生异常时,我们直接管理的内存是不会自动释放的。如果使用内置指针管理内存,且在new之后在对应的delete之前发生了异常,则内存是不会被是释放的。

void f(){
int *ip = new int(42); //动态分配一个新对象 //这段代码抛出异常,且在f中未捕获 delete ip; //在退出之前释放内存}

如果在new和delete之间发生异常,且异常未在f中被捕获,则内存就永远不会被是释放了。在函数f之外没有指针指向这块内存

智能指针和哑类

假如,我们正在使用一个C/C++都使用的网络库,代码如下:

struct destination;    //表示我们正在连接着什么struct connection;     //使用连接所需信息connection connect(destination *);   //打开连接void disconnect(connection);         //关闭给定连接void f(destination &d /*其他参数*/){
//获得一个连接,记住使用完要关闭它 connection c = connect(&d); //使用连接 //如果我们在f退出前忘记调用disconnect,就无法关闭c了}

对于这个问题,我们使用share_ptr来保证connection被正确关闭

当一个shared_ptr被销毁时,它默认地对它管理地指针进行delete操作。为了用shared_ptr来管理一个connection,我们必须首先定义一个函数来代替delete。这个删除器函数必须能够完成对shared_ptr中保存的指针进行释放操作。在本例中,我们的删除器必须接受单个类型为connection*的参数。

void end_connection(connection *p){
disconnect(*p);}

当我们创建一个shared_ptr时,可以传递一个指向删除器函数的参数

void f(destination &d /*其他参数*/){
connection c = connect(&d); shared_ptr
p(&c, end_connection); //使用连接 //当f退出时,connection会被正确关闭}

当p被销毁时,它不会对自己保存的指针执行delete,而是调用end_connection。end_connection会调用disconnect,从而确保连接被关闭。如果发生了异常,p同样会被销毁,从而连接被关闭

编写自己版本用shared_ptr管理connection的函数,并用lambda代替end_connection函数

#include 
#include
using namespace std;struct destination {
};struct connection {
};connection connect(destination* pd) {
cout << "打开连接" << endl; return connection();}void disconnect(connection c) {
cout << "关闭连接" << endl;}//未使用shared_ptr的版本void f(destination& d) {
cout << "直接管理connect" << endl; connection c = connect(&d); //忘记调用disconnect关闭连接 cout << endl;}void end_connection(connection* p) {
disconnect(*p); }//lambda不捕获局部变量,参数为connection指针,用改指针指向的对象调用disconnect即可//[](connection *p){disconnect(*p);}void f1(destination& d) {
cout << "用shared_ptr管理connect" << endl; connection c = connect(&d); shared_ptr
p(&c, end_connection); //shared_ptr
p(&c,[](connection *p){disconnect(*p);} ); //忘记调用disconnect关闭连接 cout << endl;}int main() {
destination d; f(d); f1(d); return 0;}

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

你可能感兴趣的文章
主流算法:
查看>>
RMI
查看>>
J.U.C之Future
查看>>
缓存思想分析
查看>>
一致性hash
查看>>
J.U.C之ConcurrentHashMap分析
查看>>
J.U.C之CopyOnWriteArrayList
查看>>
J.U.C之Atomic&CAS
查看>>
类的生命周期
查看>>
Joda-Time学习
查看>>
Guava扩展工具包
查看>>
Jedis分片策略-一致性Hash
查看>>
BeanFactory和FactoryBean
查看>>
用户态和内核态的概念区别
查看>>
情境领导力
查看>>
赋能:打造应对不确定性的敏捷组织
查看>>
Java 学习方法浅谈
查看>>
Jsp连接数据库大全
查看>>
WebSphere Application Server 常见问题及解答:安全
查看>>
WebSphere Application Server 常见问题及解答:集群
查看>>