C++11 implements Golang defer similar to Java finally operations.

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.
Copyright <chaishushan#gmail.com>. All rights reserved.//Use of this source code are governed by a bsd-style//license so can be found in the license file. #ifndef _defer_h_#define _defer_h_#include <functional> #include <iostream>////need support c11-std=c++11//DEFER The////statement defines an object that delays the execution of a closure function based on usage:////file* fp = fopen ("Foo.txt", "RT");/if (fp = = NULL) return false;//defer ([&] () {PR Intf ("fclose (FP) \ n"); Fclose (FP); });///char* BUF = new char[1024];//defer ([&] () {printf ("delete buf\n"); delete[] buf;}); ////Defer ([] () {printf ("Defer A:%d\n", __line__); /defer ([] () {printf ("Defer A:%d\n", __line__); /defer ([] () {printf ("Defer A:%d\n", __line__); ///{//Defer ([] () {printf ("Defer B:%d\n", __line__);}); /defer ([] () {printf ("Defer B:%d\n", __line__);}); /defer ([] () {printf ("Defer B:%d\n", __line__);}); /}////Defer ([] () {//printf ("Defer c:\n");//for (int i = 0; i < 3; ++i) {//DEFer ([&] () {defer ([&] () {//printf ("\ti =%d:begin\n", i);//defer ([&] () {printf ("\ti =%d\n ", i); });//printf ("\ti =%d:end\n", i);/}); /}//});////Note:////1. The object defined by defer executes the closure function (destructor)//2 when it goes out of scope. The object defined by defer is different within the same file identifier (generated by line number)//3. Defer may occur with the same name in the global scope (line number is the same)//4. Defer may be executed in advance (at the end of the scope)//5 When judging the statement usage. Defer used in a loop statement is invalid (at the end of the scope)//6. Defer and go language defer are not exactly equivalent////more reference:////http://blog.korfuri.fr/post/go-defer-in-cpp///http://blog.korfuri.fr/ attachments/go-defer-in-cpp/defer.hh//http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx///HTTP golang.org/doc/effective_go.html#defer//http://golang.org/ref/spec#Defer_statements//#define DEFER _defer_action _make/* ([&] () {...}); *///Auto _defer_action_line??? _ = _deferredactionctor ([&] () {...}) #define _defer_action_make auto \ _defer_action_var (_defer_action_line, __line__, _) = _deferredactionctor#define _DEFE R_action_var (A, B, c) _defer_token_cOnnect (A, B, c) #define _defer_token_connect (A, B, C) A # # # # # # c//holds the closure function class _deferredaction {private:std::function&    Lt;void () > func_;    Template<typename t> friend _deferredaction _deferredactionctor (t&& p); Template<typename t> _deferredaction (t&& p): Func_ (Std::bind (std::forward<t> (p))) {Std::cou    T << "NEW 1" << Std::endl;    } _deferredaction ();    _deferredaction (_deferredaction const&);    _deferredaction& operator= (_deferredaction const&); _deferredaction& operator= (_deferredaction&&);p ublic: _deferredaction (_deferredaction&& other        ): Func_ (Std::forward<std::function<void () >> (other.func_)) {other.func_ = nullptr;    Std::cout << "NEW 2" << Std::endl;        } ~_deferredaction () {if (func_) {func_ ();}    Std::cout << "DELETE" << Std::endl; }};template<typename t>_deferredaction _deferredactionctoR (t&& p) {return _deferredaction (std::forward<t> (P));} #endif//_defer_h_



Test:


/* * File:main.cpp * author:vicky.h * email:eclipser@163.com */#include "defer.h" #include <iostream>void sayh Ello (const char* name) {printf ("Hello%s\n", name);}    void Funtest () {printf ("funtest 1\n");    Defer ([] () {printf ("Defer C:%d\n", __line__);});    Defer ([] () {printf ("Defer C:%d\n", __line__);});    Defer ([] () {printf ("Defer C:%d\n", __line__);}); printf ("Funtest 2\n");}    /* * */int main (void) {defer ([] () {printf ("Defer A:%d\n", __line__);});    Defer ([] () {printf ("Defer A:%d\n", __line__);});    Defer ([] () {printf ("Defer A:%d\n", __line__);});    Defer ([] () {SayHello ("Jack");});        {Defer ([] () {printf ("Defer B:%d\n", __line__);});        Defer ([] () {printf ("Defer B:%d\n", __line__);});        Defer ([] () {printf ("Defer B:%d\n", __line__);});    Std::cout << "In code scope" << Std::endl; } std::cout << "\ n---------------------------" << Std::endl;    Std::cout << "Done 1" << Std::endl;    Std::cout << "Done 2" << Std::endl;        Std::cout << "Done 3" << Std::endl;        Throw "Exception happen";        Std::cout << "\ n---------------------------" << Std::endl;    Funtest (); return 0;}


Git:http://git.oschina.net/eclipser/defer4cpp.git


Note that the above code needs to support c++11:-std=c++11


Output:

NEW 1
NEW 1
NEW 1
NEW 1
NEW 1
NEW 1
NEW 1
In Code scope
Defer b:42
DELETE
Defer b:41
DELETE
Defer b:40
DELETE


---------------------------
Done 1
Done 2
Done 3


---------------------------
Funtest 1
NEW 1
NEW 1
NEW 1
Funtest 2
Defer c:22
DELETE
Defer c:20
DELETE
Defer c:18
DELETE
Hello, Jack.
DELETE
Defer a:35
DELETE
Defer a:33
DELETE
Defer a:31
DELETE


Run finished; Exit value 0; Real-time: 20ms; User: 0ms; System: 0MS


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.