本篇内容介绍了“c++如何实现Go的defer功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在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类:
#include <functional>typedef std::function<void()> 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;}}
这样就实用且方便得多了。下面给出完整代码以及测试用例:
#include <functional>using namespace std;typedef std::function<void()> 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功能”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!
--结束END--
本文标题: C++如何实现Go的defer功能
本文链接: https://www.lsjlt.com/news/296204.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
一口价域名售卖能注册吗?域名是网站的标识,简短且易于记忆,为在线用户提供了访问我们网站的简单路径。一口价是在域名交易中一种常见的模式,而这种通常是针对已经被注册的域名转售给其他人的一种方式。
一口价域名买卖的过程通常包括以下几个步骤:
1.寻找:买家需要在域名售卖平台上找到心仪的一口价域名。平台通常会为每个可售的域名提供详细的描述,包括价格、年龄、流
443px" 443px) https://www.west.cn/docs/wp-content/uploads/2024/04/SEO图片294.jpg https://www.west.cn/docs/wp-content/uploads/2024/04/SEO图片294-768x413.jpg 域名售卖 域名一口价售卖 游戏音频 赋值/切片 框架优势 评估指南 项目规模
0