C++实现Go的defer功能(示例代码)_第1页
C++实现Go的defer功能(示例代码)_第2页
C++实现Go的defer功能(示例代码)_第3页
C++实现Go的defer功能(示例代码)_第4页
C++实现Go的defer功能(示例代码)_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C++实现Go的defer功能(示例代码)在Go语言中有一个关键字:defer,它的作用就是延迟执行后面的函数,在资源释放方面特别有用,比如下面一段C/C++的示例代码:

voidtest()

FILE*fp=fopen("test.txt","r");

if(nullptr==fp)

return;

if(...)

fclose(fp);

return;

if(...)

fclose(fp);

return;

if(...)

fclose(fp);

return;

fclose(fp);

}

在每一处返回之前都需要调用fclose来关闭文件句柄,中间的流程中断越多,越是容易遗漏调用fclose导致未正常关闭文件。

C++可以使用shared_ptr,auto_ptr之类的智能指针来管理分配的内存,但是像上面这种情况C++并没有现成的可使用的代码来处理。而Go语言提供了defer关键字来解决此类问题,Go可以按如下方式来写:

functest(){

file,err:=os.Open("test.txt")

iferr!=nil{

return

deferfile.Close()

if...{

return

if...{

return

if...{

return

}

只需要使用一句:

deferfile.Close()

即可,Go会自动在return之后调用defer后面的函数。我们再看看下面的示例:

packagemain

import(

"fmt"

functest()(nint,errerror){

deferfmt.Println("测试1")

deferfmt.Println("测试2")

deferfmt.Println("测试3")

returnfmt.Println("test")

funcmain(){

test()

}

它的输出为:

test

测试3

测试2

测试1

可以看出有多个defer时,按照先进后出的方式执行的。

C++中我们可以利用析构函数来实现,而且C++的局部变量析构规则也是按照先进后出的方式执行的。为此,我们需要定义一个Defer类:

#includefunctional

typedefstd::functionvoid()fnDefer;

classDefer

public:

Defer(fnDeferfn):m_fn(fn)

~Defer()

if(m_fn)

m_fn();

private:

fnDeferm_fn;

};

这样,前面的C++示例代码可以写成:

voidtest()

FILE*fp=fopen("test.txt","r");

if(nullptr==fp)

return;

Deferd([]()

fclose(fp);

if(...)

return;

if(...)

return;

if(...)

return;

}

不用再在每一处返回前手动写代码关闭文件了。

但是这里还有一点不便之处就是需要手写一个lambda表达式和手动定义一个变量,这个很好解决,使用宏来处理。

#definedefer1(a,b)a##b

#definedefer2(a,b)defer1(a,b)

#definedefer(expr)Deferdefer2(__Defer__,__COUNTER__)([](){expr;})

为了方便在同一函数多处使用,定义了defer宏来给变量命不同的名,前面的代码可以改为:

voidtest()

FILE*fp=fopen("test.txt","r");

if(nullptr==fp)

return;

defer(fclose(fp));

if(...)

return;

if(...)

return;

if(...)

return;

}

这样就实用且方便得多了。下面给出完整代码以及测试用例:

#includefunctional

usingnamespacestd;

typedefstd::functionvoid()fnDefer;

classDefer

public:

Defer(fnDeferfn):m_fn(fn)

~Defer()

if(m_fn)

m_fn();

private:

fnDeferm_fn;

#definedefer1(a,b)a##b

#definedefer2(a,b)defer1(a,b)

#definedefer(expr)Deferdefer2(__Defer__,__COUNTER__)([](){expr;})

classTest

public:

voidf(inti)

printf("f:%d%p\n",i,this);

intmain(intargc,char*argv[])

Testt;

printf("t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论