value адвайсы
Главная, Основные концепции, АОП, Адвайсы
Value-адвайс аналогичен обычному адвайсу, за исключением того, что внедряется в аспект через агрегацию. Описывается он с помощью конструкции fas::value:
typedef fas::value<_counter_, int> counter_advice;
Этот тип адвайсов удобен для вынесения в аспект класса отдельных полей аспектного класса. Если необходимо описать часть состояния одним адвайсом, то делается это промежуточную структуру, которая вноситься в аспект как обычный адвайс.
Доступ к обычному адвайсу и value-адвайсу семантически идентичен. Любой C++ класс, объект которого можно создать с конструктором по умолчанию, и который может быть использован в качестве базового, может быть вынесен в аспект как обычный адвайс, так и как value-адвайс. Однако, в последнем случае, если адвайс не имеет состояния, он все равно увеличивает sizeof аспектного класс 1 байт, т.к. внедряется через агрегацию. Это может иметь значение если аспектный класс не имеет состояния, но реализует обширный функционал, который вынесен в аспекты.
В следующем примере sizeof(counter<>)
равен sizeof(int)
, что соответствует внедренному fas::value<_counter_, int>
. Если оставшиеся три авдвайса внедрить как value-адвайсы (т.е. просто заменить fas::advice
на fas::value
), то соответственно увеличиться и sizeof(counter<>)
. В большинстве систем размер увеличиться с четырех байт до восьми (по одному байту на каждый дополнительный value-адвайс и плюс один байт на выравнивание)
#include <fas/aop.hpp>
#include <iostream>
struct _counter_;
struct _inc_;
struct _dec_;
struct _show_;
struct ad_inc
{
template<typename T>
void operator()(T& t)
{
t.get_aspect().template get<_counter_>()++;
}
};
struct ad_dec
{
template<typename T>
void operator()(T& t)
{
t.get_aspect().template get<_counter_>()--;
}
};
struct ad_show
{
template<typename T>
void operator()(T& t) const
{
typedef typename T::aspect::template advice_cast<_counter_>::type value_type;
value_type counter = t.get_aspect().template get<_counter_>();
std::cout << "counter: " << counter << std::endl;
}
};
struct counter_aspect: fas::aspect< fas::type_list_n<
fas::value<_counter_, int>,
fas::advice<_inc_, ad_inc>,
fas::advice<_dec_, ad_dec>,
fas::advice<_show_, ad_show>
>::type > {};
template<typename A = fas::aspect<> >
class counter
: public fas::aspect_class< typename fas::merge_aspect<A, counter_aspect>::type >
{
public:
void inc() { this->get_aspect().template get<_inc_>()(*this); }
void dec() { this->get_aspect().template get<_dec_>()(*this); }
int get() const { return this->get_aspect().template get<_counter_>(); }
void show() const { this->get_aspect().template get<_show_>()(*this); }
};
int main()
{
counter<> c;
c.inc(); c.inc(); c.inc();
c.dec();
c.show();
}