C++如何实现Go的defer功能
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,本篇内容介绍了"C++如何实现Go的defer功能"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在G
千家信息网最后更新 2025年12月02日C++如何实现Go的defer功能
本篇内容介绍了"C++如何实现Go的defer功能"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
在Go语言中有一个关键字:defer,它的作用就是延迟执行后面的函数,在资源释放方面特别有用,比如下面一段C/C++的示例代码:
void test(){ 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可以按如下方式来写:
func test() { file, err := os.Open("test.txt") if err != nil { return } defer file.Close() if ... { return } if ... { return } if ... { return }}只需要使用一句:
defer file.Close()
即可,Go会自动在return之后调用defer后面的函数。我们再看看下面的示例:
package mainimport ( "fmt")func test() (n int, err error) { defer fmt.Println("测试1") defer fmt.Println("测试2") defer fmt.Println("测试3") return fmt.Println("test")}func main() { test()}它的输出为:
test
测试3
测试2
测试1
可以看出有多个defer时,按照先进后出的方式执行的。
C++中我们可以利用析构函数来实现,而且C++的局部变量析构规则也是按照先进后出的方式执行的。为此,我们需要定义一个Defer类:
#includetypedef std::function fnDefer;class Defer{public: Defer(fnDefer fn) : m_fn(fn) { } ~Defer() { if(m_fn) m_fn(); }private: fnDefer m_fn;};
这样,前面的C++示例代码可以写成:
void test(){ FILE* fp = fopen("test.txt", "r"); if (nullptr == fp) return; Defer d([&]() { fclose(fp); }); if (...) { return; } if (...) { return; } if (...) { return; }}不用再在每一处返回前手动写代码关闭文件了。
但是这里还有一点不便之处就是需要手写一个lambda表达式和手动定义一个变量,这个很好解决,使用宏来处理。
#define defer1(a,b) a##b#define defer2(a, b) defer1(a, b)#define defer(expr) Defer defer2(__Defer__,__COUNTER__) ([&](){expr;})为了方便在同一函数多处使用,定义了defer宏来给变量命不同的名,前面的代码可以改为:
void test(){ FILE* fp = fopen("test.txt", "r"); if (nullptr == fp) return; defer(fclose(fp)); if (...) { return; } if (...) { return; } if (...) { return; }}这样就实用且方便得多了。下面给出完整代码以及测试用例:
#includeusing namespace std;typedef std::function fnDefer;class Defer{public: Defer(fnDefer fn) : m_fn(fn) { } ~Defer() { if(m_fn) m_fn(); }private: fnDefer m_fn;};#define defer1(a,b) a##b#define defer2(a, b) defer1(a, b)#define defer(expr) Defer defer2(__Defer__,__COUNTER__) ([&](){expr;})class Test{public: void f(int i) { printf("f:%d %p", i, this); }};int main(int argc, char *argv[]){ Test t; printf("test:%p", &t); defer(t.f(1)); defer(t.f(2)); defer(t.f(3)); return 0;}
结果如下:
"C++如何实现Go的defer功能"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
C++
测试
代码
函数
变量
文件
方式
示例
t.f
功能
实用
先进
关键
关键字
内容
就是
情况
手动
更多
知识
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
鲲腾量子安全数据库
delphi 数据库
vc 数据库 类库
建立低收入人口数据库
数据库怎么删除插入记录
网络安全属于属于党管吗
漯河计算机网络技术
农信银行软件开发待遇
青少年网络安全试题知识
关于网络安全的校园通讯稿
网络安全巡检模板
北京先进软件开发方法
多用户商城软件开发
软件开发评价指标主要有哪些
国家网络安全宣传试卷
天津软件开发学校
云服务器上传文件安全性
江门通信软件开发供应商
北京清能互联网科技公司
服务器 ftp 访问
网络安全文章推荐
学软件开发哪个靠谱
南京天象网络技术有限公司
租mt4服务器
防火墙软件开发
广州雅量软件开发公司招聘
服务器云端硬盘怎么换
国际社会对网络安全的贡献
高性能服务器供应价格
网络安全类商家有哪些