这篇文章主要介绍“c++怎么实现Go的defer功能”,在日常操作中,相信很多人在C++怎么实现Go的defer功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++怎么实现Go的defer功能”的疑惑有所
这篇文章主要介绍“c++怎么实现Go的defer功能”,在日常操作中,相信很多人在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类:
#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\n", i, this);}};int main(int arGC, char *argv[]){Test t;printf("test:%p\n", &t);defer(t.f(1));defer(t.f(2));defer(t.f(3));return 0;}
结果如下:
以上在VC 2015以及GCC、Clang下测试通过。
到此,关于“C++怎么实现Go的defer功能”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!
--结束END--
本文标题: C++怎么实现Go的defer功能
本文链接: https://www.lsjlt.com/news/297790.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
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0