C++之AOP

C++之AOP

AOP是近年炒得很热,但却用得很少的一门技术,不过这并不能阻止我去学习它。既然能一度炒得火热,必定有过人之处。说AOP是一种思想或许更适合一些,它并不描述哪一种专有的技术,也不指定实现方式。

众所周知,C++没有丰富的动态类型信息,更没有动态生成类的功能(C++类型在编译后就基本上没有类型存在了),所以无法像java一样采用动态代理来实现AOP。

Aspect C++是C++的一个AOP实现,它使用了插入代码的方法。

一个典型的Aspect C++示例需要一个C++源文件(.cpp)、一个Aspect C++源文件(.ah),通过ac++编译器把C++源文件和Aspect C++源文件转换成混合的C++源文件(如果有头文件也会转换),最后通过普通的C++编译器编译出可执行文件。

下面是一个简单的示例:

1、C++源文件:
#include  < stdio.h >

class  A {
public :
  
int  a( int  i,  float  b);
};

int  A::a( int  i,  float  b) {
  printf(
" inside A::a(%d, %f)/n " , i, b);
  
return  i;
}

void  b( char  c,  char   * str) {
  printf(
" inside b(%c, %s)/n " , c, str);
}

int  main() {
  A a;
  a.a(
4711 3.14 );
  b(
' H ' " ello World " );
  return 0;
}

2、Aspect C++源文件:
#include  < stdio.h >

aspect Action {
  advice execution(
" % A::%() " ||  execution( " % b() " ) : around()  {
    printf(
" A: before(exec) %s/n " , JoinPoint::signature());
    printf(
" that  : %p/n "  , tjp -> that());
    printf(
" target: %p/n "  ,tjp -> target());
    tjp
-> proceed();
    printf(
" A: after(exec) %s/n " , JoinPoint::signature());
  }
  advice call(
" % A::%() " ||  call( " % b() " ) : around()  {
    printf(
" A: before(call) %s/n " , JoinPoint::signature());
    printf(
" that  : %p/n "  , tjp -> that());
    printf(
" target: %p/n "  ,tjp -> target());
    tjp
-> proceed();
    printf(
" A: after(call) %s/n " , JoinPoint::signature());
  }
};

aspect ActionB {
  advice execution(
" % A::%() " ||  execution( " % b() " ) : around()  {
    printf(
" B: before(exec) %s/n " , JoinPoint::signature());
    printf(
" that  : %p/n "  , tjp -> that());
    printf(
" target: %p/n "  ,tjp -> target());
    tjp
-> proceed();
    printf(
" B: after(exec) %s/n " , JoinPoint::signature());
  }
  advice call(
" % A::%() " ||  call( " % b() " ) : around()  {
    printf(
" B: before(call) %s/n " , JoinPoint::signature());
    printf(
" that  : %p/n "  , tjp -> that());
    printf(
" target: %p/n "  ,tjp -> target());
    tjp
-> proceed();
    printf(
" B: after(call) %s/n " , JoinPoint::signature());
  }
};

简单说明一下:
1、“aspect Action”定义了一个“方面”,名字是“Action”,定义一个方面可以理解为“我关注程序的这个方面”。
2、“advice 切入点:位置”定义一个“处理方法”,在切入点的指定位置上执行代码。切入点可以选择call、execution、construction、destruction,分别表示调用、执行、构造函数、析构函数。执行点可以选择before、after、around,分别表示在这些切入点的前面、后面或替换掉整个函数。
3、tpj表示thisJoinPoint,表示切入点本身。上面的例子由于使用around替换了整个执行过程,所以要执行原来的操作还需要调用tpj->proceed()。这里的around完成的功能可由一个before和一个after代替
4、切入点的匹配模式。切入点通过字符串来匹配要切入的操作,“%”字符表示匹配任意类型(或名字),在AspectJ中,这个字符是“*”,由于C++中“*”用来定义指针,所以在Aspect C++中用“%”;“...”用来匹配任意个参数。

编译:
首先运行ac++ -p <你的源文件所在目录> -d <输出文件目录> -I<附加头文件目录>,这一步会转换C++源文件和Aspect C++源文件。

如果在安装了VC,编译时可指定INCLUDE路径及_WIN32宏。
ac++ -p <你的源文件所在目录> -d <输出文件目录> -I<附加头文件目录> -I"C:/Program Files/Microsoft Visual Studio 8/VC/include" -D_WIN32

然后直接编译:
cl <源文件名>.cc

上面这个程序在处理前运行结果如下:
F:/soft/ac/examples/Action > main
inside A::a(
4711 3.140000 )
inside b(H, ello World)

经Aspect C++处理后运行结果:
F:/soft/ac/examples/Action - out > main
A: before(call) 
int  A::a( int , float )
that  : 
00000000
target: 0012FF73
B: before(call) 
int  A::a( int , float )
that  : 
00000000
target: 0012FF73
A: before(exec) 
int  A::a( int , float )
that  : 0012FF73
target: 0012FF73
B: before(exec) 
int  A::a( int , float )
that  : 0012FF73
target: 0012FF73
inside A::a(
4711 3.140000 )
B: after(exec) 
int  A::a( int , float )
A: after(exec) 
int  A::a( int , float )
B: after(call) 
int  A::a( int , float )
A: after(call) 
int  A::a( int , float )
A: before(call) 
void  b( char , char   * )
that  : 
00000000
target: 
00000000
B: before(call) 
void  b( char , char   * )
that  : 
00000000
target: 
00000000
A: before(exec) 
void  b( char , char   * )
that  : 
00000000
target: 
00000000
B: before(exec) 
void  b( char , char   * )
that  : 
00000000
target: 
00000000
inside b(H, ello World)
B: after(exec) 
void  b( char , char   * )
A: after(exec) 
void  b( char , char   * )
B: after(call) 
void  b( char , char   * )
A: after(call) 
void  b( char , char   * )
转自 http://qiezi.javaeye.com/blog/26673

 

aspectc

http://www.cs.ubc.ca/labs/spl/projects/aspectc.html

http://sailhome.cs.queensu.ca/~bram/aspicere/index.html

aspectcpp

http://www.oschina.net/p/aspectcpp

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AOP(面向切面编程)是一种编程思想,它将通用的功能与业务逻辑分离,使得代码更清晰、更易维护。C++本身并不支持AOP,但可以通过使用一些技术手段来实现AOP。 一种常见的实现AOP的方式是使用代理模式。代理模式是通过创建一个代理对象来控制对原始对象的访问,代理对象可以在被代理对象执行前后加入一些通用的功能。 下面是一个使用代理模式实现AOP的示例。 首先,我们定义一个接口类(Subject)和一个实现类(RealSubject): ```c++ class Subject { public: virtual void request() = 0; }; class RealSubject : public Subject { public: void request() override { std::cout << "RealSubject::request" << std::endl; } }; ``` 然后,我们定义一个代理类(Proxy),它包含一个指向RealSubject对象的指针,并在执行request()方法前后加入一些通用的功能: ```c++ class Proxy : public Subject { public: Proxy(Subject* realSubject) : m_realSubject(realSubject) {} void request() override { // 在执行request()方法前执行一些通用的功能 std::cout << "Before RealSubject::request" << std::endl; // 调用RealSubject的request()方法 m_realSubject->request(); // 在执行request()方法后执行一些通用的功能 std::cout << "After RealSubject::request" << std::endl; } private: Subject* m_realSubject; }; ``` 最后,我们可以使用代理类来代理RealSubject对象,并在执行request()方法前后加入一些通用的功能: ```c++ int main() { RealSubject realSubject; Proxy proxy(&realSubject); proxy.request(); return 0; } ``` 这就是使用代理模式实现AOP的一个简单示例。在实际项目中,我们可以使用更复杂的技术手段来实现AOP,如使用宏、函数指针和模板等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值