原标题:RAII 妙用之 ScopeExit

什么是RAII

Resource Acquisition Is Initialization, 资源获取即初始化,将资源的生命周期与一个对象的生命周期绑定,举例来说就是,把一些资源封装在类中,在构造函数请求资源,在析构函数中释放资源且绝不抛出异常,而一个对象在生命周期结束时会自动调用析构函数,即资源的生命周期与一个对象的生命周期绑定。

RAII的应用

见如下代码:

std::mutex mutex;

voidfunc{}

voidNoRAII{

mutex.lock;

func;

if(xxx) {

mutex.unlock; // 多次需要调用unlock,还有可能忘记调用unlock导致一直持有锁

return;

}

...

mutex.unlock;

}

voidRAII{ // 不需要显式调用unlock

std::lock_guard< std::mutex> lock(mutex);

func;

if(xxx) {

return;

}

...

return;

}

RAII的应用非常多,C++的STL基本都遵循RAII规范,典型的如vector, string, lock_guard, unique_lock, shared_ptr, unique_ptr等,这里不会介绍这些STL的使用,相信大家也都会使用,如果有相关需求可以留言。

RAII的巧用

最近研究了boost中的ScopeExit,发现这是个很高级的特性,利用RAII特性,可以在作用域结束时自动关闭已经打开的资源或做某些清理操作,类似于unique_ptr,但又比unique_ptr方便,不需要自定义delete函数。

举例: 如果没有ScopeExit

voidtest{

char*test = newchar[ 100];

if(a) {

delete[] test; // count 1

return;

}

xxx;

if(b) {

delete[] test; // count 2

return;

}

...

delete[] test; // count 3

}

使用了ScopeExit

voidtest{

char*test = newchar[ 100];

std:: ofstream ofs( "test.txt");

ScopeExit {

delete[] test; // 在test函数生命周期结束后自动执行delete[]操作

ofs.close; // 在生命周期结束后自动关闭文件,这里只是举个不恰当例子,ofstream自动生命周期结束后就会关闭

};

if(a) {

return;

}

xxx;

if(b) {

return;

}

...

}

当然,正常C++代码不鼓励使用裸指针,可以使用智能指针来申请资源,这里只是举个例子,使用ScopeExit也可以用于处理文件资源的关闭等等。

两者代码比较后优劣程度显而易见,不使用ScopeExit需要在return前多次做资源清理操作,而使用了ScopeExit则只需做一次声明后在作用域结束后会自动进行相关的资源清理操作,方便而且不易出错。

ScopeExit实现

这里参考boost使用C++11实现了一套ScopeExit机制

classScopeExit{

public:

ScopeExit = default;

ScopeExit( constScopeExit&) = delete;voidoperator=( constScopeExit&) = delete;

ScopeExit(ScopeExit&&) = default;ScopeExit& operator=(ScopeExit&&) = default;

template< typenameF, typename... Args>ScopeExit(F&& f, Args&&... args) {func_ = std::bind( std::forward(f), std::forward(args)...);}

~ScopeExit {if(func_) {func_;}};

private:std::function< void> func_;};

# define_CONCAT(a, b) a##b# define_MAKE_SCOPE_( line) ScopeExit _CONCAT(defer, line) = [&]

# undefSCOPE_GUARD# defineSCOPE_GUARD _MAKE_SCOPE_(__LINE__)

使用方式如下:

voidtest{char*test = newchar[ 100];std:: ofstream ofs( "test.txt");SCOPE_GUARD{delete[] test;ofs.close;};if(a) {return;}...if(b) {return;}...}

1、 C++ 多线程的互斥锁应用RAII机制

2、 为什么要分页?如何分页?分页后地址如何转化?

3、 C语言指针:从底层原理到花式技巧,用图文和代码帮你讲解透彻返回搜狐,查看更多

责任编辑:

c语言 raii 用法日志,RAII 妙用之 ScopeExit相关推荐

  1. c语言 raii 用法日志,C 语言实现 RAII

    尽管有许多的争议,但我还是觉得 C++ 中的 RAII 惯用法是个好东西,也是写 C 代码时唯一怀念的 C++ 特性.下面是一些 C 语言实现 RAII 的方法: gcc #define RAII_V ...

  2. c语言 raii 用法日志,陈硕的Blog

    陈硕(giantchen_AT_gmail_DOT_com) 2012-01-28 我在<Linux 多线程服务端编程:使用 muduo C++ 网络库>第 1.9 节"再论 s ...

  3. c语言指针用法有哪些

    c语言指针用法: 一,指针定义: 指针变量的取值范围取值0~4G,是一种数据类型(无符号整数,代表了内存编号).它可以用来定义变量(与int.long一样),与int.long不同的它存储整数代表了内 ...

  4. C语言STATIC用法

    C语言STATIC用法 转自:http://blog.csdn.net/vagrantisme/article/details/4083722       1. static 变量 静态变量的类型 说 ...

  5. go 正则表达式分组匹配_Go语言正则表达式用法实例小结【查找、匹配、替换等】...

    本文实例讲述了Go语言正则表达式用法.分享给大家供大家参考,具体如下: Go语言的正则表达式使用很简单,示例代码: 复制代码 代码如下: package test import ( "fmt ...

  6. R语言 sub()用法

    R语言 sub()用法 subR语言中的函数用于替换字符串中模式的第一个匹配项.如果有一个字符串元素向量,那么它将替换所有元素中模式的第一个匹配项. 用法: sub(pattern, replacem ...

  7. C语言continue用法

    C语言continue用法 continue只是跳出当前循环,并不会跳出整个while循环. For example: 建立 showchar2.c 1 #include <stdio.h> ...

  8. c语言sleep作用,c语言sleep用法是什么?

    小编以前Sleep(1000)等于一秒,现在sleep(1)等于一秒,,,什么情况恭喜你找到共度一生的灵魂伴侣,婚姻是人生大事,小编也相信你做出的会是最明智的决定,到时有了爱的结晶生了可爱的宝宝,别忘 ...

  9. c语言指针用法及实际应用详解,通俗易懂超详细

    c语言指针用法及实际应用详解,通俗易懂超详细! \\\插播一条:文章末尾有惊喜哟~/// 今天给大家来讲解一下指针. 我会由浅到深,最后联合实际应用讲解,让大家学会指针的同时,知道大佬们都用指针来干嘛 ...

最新文章

  1. java for 执行顺序_java – @BeforeMethod和继承 – 执行顺序(TestNG)
  2. Java @responsebody,springMVC 使用注解@ResponseBody 不能返回JSON数据
  3. css演练 0920 个人简历的制作
  4. 知名投资机构董事总经理在培训中晕倒后去世,这个培训究竟是什么?
  5. centos6和centos7防火墙的关闭
  6. c语言学习进阶-C语言程序出错处理
  7. Oracle 11g EM删除重建的方法
  8. 2020北理工夏令营机试
  9. 从java 转到 c# 知识点
  10. C 中的左值(Lvalues)和右值(Rvalues)
  11. 计算机系统保密检查整改情况函,民政局保密工作整改情况的报告
  12. 一个美国人在上海-American McGee
  13. NPS, 校外连接校园网
  14. 第三章 MapReduce框架原理
  15. 「补课」进行时:设计模式(2)——通过一个超级汽车工厂来了解工厂模式
  16. phython基础之数据类型和变量
  17. win7(32bit)下完整的搭建apache(2.2.x)+openssl(0.9.6-1.0.1升级)过程
  18. 你运营的公众号文章阅读量上不来,怎么回事?
  19. 解决你关于域名过期且没有备案的问题
  20. 区块链在信用借贷中的应用

热门文章

  1. 海贼王热血航线正在连接服务器,《航海王热血航线》连接服务器失败怎么解决 连接服务器失败解决方法...
  2. aws sqs_基准SQS
  3. EMC潘国林: 大话存储系列之月光宝盒(块存储)
  4. Excel做成绩表时自动实现同分同名次
  5. 项目管理手记 12 ERP选型,不要做 充气哈蟆
  6. 吞吐量的概念出自 MBA智库百科
  7. VMware vSphere client 中英文语言界面设置
  8. 人工智能深度学习火起来的原因
  9. 使用栈计算前缀表达式
  10. amaplocation无法获取高度_Revit二次开发——净空高度分析插件的开发思路