2.4 方向
方向是AspectC++的语言元素用来收集以模块化的方法实现共同横切关注的引入和建议代码的。这将方向置于管理共同状态信息的位置。它们由不同的方向声明声明构成,作为C++类概念的扩展。基本的方向声明结构和常见的C++定义完全一样,除了使用关键词aspect
代替了class
,struct
或者union
。基于此,方向可以有许多属性、方法,并且可以继承自多个类甚至其它的方向。
例:方向声明
aspect Counter {
static int m_count;
pointcut counted() = "Circle" || "Polygon";
advice counted() : slice struct {
class Helper {
Helper() { Counter::m_count++; }
} m_counter;
}
advice execution("% main(...)") : after() {
cout << "Final count: " << m_count << " objects" << endl;
}
};
... and at an appropriate place
#include "Counter.ah"
int Counter::m_count = 0;
在这个例子中,一系列类的对象实例数量被限定了。因此,在点切描述的类中引入属性m_counter
将在实例构造时增加全局计数器。通过对main
函数应用建议代码,当程序中止后最终的对象实例将会展示出来。
这个例子也可以用抽象方向重写这样就可以为了复用归档成一个方向库。它只需要重新实现点切声明来成为纯虚。
例:抽象方向
aspect Counter {
static int m_count;
Counter() : m_count(0) {}
pointcut virtual counted() = 0;
...
};
它现在可以继承自Counter
,能过程序化重新实现counted
来指代真正的点切表达式。
例:复用抽象方向
aspect MCounter : public Counter {
pointcut counted() = derived("Shape");
};
2.4.1 方向安装
默认情况下,AspectC++中的方向是自动安装为全局对象的。其背后的设计理由是方向也可以提供全局程序属性,因此总是可以访问的。然而在一些特殊的案例下,可能需要改变这种表现行为。例如,在操作系统上下文中,方向应该安装到每个进程或者线程中。
可以通过分别定义静态方法aspectof
来改变默认的安装模式。aspectOf
在其他方面生成一个方向。这个方法应该总是可以返回一个合适的方向的实例。
**例:使用aspectof
安装方向
aspect ThreadCounter : public Counter {
pointcut counted() = "Thread";
advice counted() : ThreadCounter m_instance;
static ThreadCounter *aspectof() {
return tjp->target()->m_instance;
}
};
向Thread
中引入m_instance
保证了每个线程对象有这个方向的一个实例。通过调用aspectof
,可以在任意结合点获得这个实例,这对于访问建议代码和对象成员是十分关键的。出于这个原因,aspectof
中的代码通过下一节描述的方法获得访问真正结合点的全部权限。