c语言 raii 用法日志,RAII 妙用之 ScopeExit

原标题: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语言指针:从底层原理到花式技巧,用图文和代码帮你讲解透彻返回搜狐,查看更多

责任编辑:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值