本篇内容介绍了“C++如何实现Go的defer功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
成都创新互联公司是专业的长白网站建设公司,长白接单;提供网站设计制作、网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行长白网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
在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 main
import (
"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++如何实现Go的defer功能
当前链接:http://www.jxjierui.cn/article/ijsces.html


咨询
建站咨询
