To apply AOP in C + + is not as convenient as in other interpreter-based languages, as a static language, if you create a wrapper for a function or class method, embedding the pre-call code and the code after the call in the wrapper can also achieve a certain level of code weaving effect. Before c++11, it is not simple to give a function or method a wrapper that returns the result of the call, but in c++11 it is possible to use the function template and the presumption of the return type By generating an inline class object's constructor to perform before actions, destructors to implement after actions, and specific before and action actions can be represented by the lambda live function, which is much easier to implement, You can also set an object to give the Before/after action parameters.
First look at the wrapper of the function:
Template<typename T, TypeName probe>struct wrapper<t*, probe>{typedef function<void (Probe) > Wrapfu Nctype; t* _func; Probe _probe; Wrapfunctype _after, _before; struct wrapinternal{wrapper<t*, probe>* _wrapper; Wrapinternal (wrapper<t*,probe>* W): _wrapper (w) {_wrapper->_before (_wrapper->_probe); } ~wrapinternal () {_wrapper->_after (_wrapper->_probe); } }; Wrapper (t* func, Probe p, wrapfunctype callbefore = [] (Probe p) {}, Wrapfunctype callafter = [] (Probe p) {}): _probe (p) {_func = func;
_after = Callafter; _before = Callbefore; } template<typename ... Args> auto Operator () (args && ... args)->decltype ((*_func) (args ...) {wrapinternal _w (this); Return (*_func) (args ...); }};
This wrapper can wrap a function, and the invocation of the generated object is called just like the original function's call:
int foo_int (int a) { cout << "Foo_int:" << a << Endl; Return a * A; }
......
typedef WRAPPER<INT (*) (int), int> T1; T1 W4 (&foo_int, +, [] (int v) {cout << "w4<100> before" << Endl;}, [] (int v) {cout < ;< "w4<100> after" << Endl; }); cout << W4 (+) << Endl;
If you want to make a wrapper for a class method, you can do so as follows:
Template<typename T, TypeName object, TypeName Probe>struct wrapper<t, object, probe>{typedef function< void (Probe) > Wrapfunctype; T _method; Object _obj; Probe _probe; Wrapfunctype _after, _before; struct wrapinternal{wrapper<t, Object, probe>* _wrapper; Wrapinternal (Wrapper<t, Object, probe>* W): _wrapper (w) {_wrapper->_before (_wrapper->_probe); } ~wrapinternal () {_wrapper->_after (_wrapper->_probe); } }; Wrapper (t&& method, object&& obj, Probe p, Wrapfunctype Callbefore = [] (Probe p) {}, Wrapfunctype callafter = [] (Probe p) {}): _probe (P) { _method = method; _obj = obj; _after = Callafter; _before = Callbefore; } template<typename ... Args> Auto Operator ()(args && ... args)->decltype (bind (_method, _obj, args ...) (args ...)) {wrapinternal _w (this); Auto B = Bind (_method, _obj, args ...); Return B (args ...); }};
When used, set the class name, object, and method:
struct foo{ Foo () { cout << "Foo::foo" << Endl; } void bar (int v) { cout << "Foo::bar" << v << Endl; }};
......
typedef WRAPPER<VOID (Foo::*) (int), foo*, const char*> T2; Foo F; T2 W5 (&foo::bar, &f, "method", [] (const char* v) {cout << w5<method> before << Endl ;}, [] (const char* v) {cout << "w5<method> after" << Endl;}); W5 (500);
The wrapper object generated by these 2 methods can also be used as a function to set up a wrapper, that is, through this method can implement multiple levels of nested wrapper, call the time from the outside to the inside of the order call before action, after the original function or method, The after action is then called from the inside to the outside order, and the return value of the original function or method is returned.
Visit Https://github.com/icandroid/wrapper11 to view the source code and demo examples for this wrapper.
Call wrapper based on c++11