[aspectc-user] syntax question

Olaf Spinczyk olaf at ivs.cs.uni-magdeburg.de
Tue Feb 12 11:31:28 CET 2002


Hi,

On Tuesday, 12. February 2002 10:44, you wrote:
> I have class A with member function virtual void a(), and derived class B
> which overrides a(). I wish to apply a before() operation to each execution
> of a(). So the pointcut can be
> pointcut c() = execution("void %::a()");
> However if a third unrelated class C also has member fn a() then this will
> be also be selected by the pointcut.  What I want to do is select a() only
> where it is a member of a class derived from A.  Does the compiler support
> this?  I have experimented with within() and base() but suspect that these
> are not supported yet, or maybe I just have the wrong syntax.

'within(derived("A")) && execution("void %::a()")' is the right pointcut for 
your scenario. The only problem is that "within" in not included in 
"0.4pre2". You will find this feature in the next release, which will come 
today :-)

here is the code (tested):
-------------------------------------------------------------------
#include <iostream.h>

aspect O
 {
   advice within(derived("A")) && execution ("void %::a()") :
      void before ()
      { cout << "before a()" << endl; }
 };

class A
 {
   public:
      int i;
      virtual void a () {}
 };

class B : public A
 {
   public:
      void a () {}
 };

class C
 {
   public:
      void a () {}
 };

int main ()
 {
   B b;
   C c;

   b.a ();
   c.a ();
 }
-----------------------------------------------------------------------------
The advice is only executed for b.c().


> On a separate issue, once into the before() advice I wish to access
> existing attributes and methods of A, is this possible?

Yes, it is... (tested as well)
-----------------------------------------------------------------------------
class A;

aspect O
 {
   void access_A(A* aptr);

   advice that(aptr) && execution ("void %::a()") :
      void before (A *aptr)
      { access_A(aptr);
      }
 };

class A
 {
   public:
      int i;
      A() { i = 4711; }
      virtual void a () {}
 };

// B and C as show above

void O::access_A (A *aptr)
 { cout << "before a(), i is " << aptr->i << endl;
 }

// main as show above
------------------------------------------------------------------------------

By the way, 'that("A")' or 'that(aptr)' has the same effect as 
'within(derived("A"))' in this example. So you can continue with your 
experiments without waiting for the newest version.

The difference between 'derived' and 'that' is that 'derived' statically 
looks for the scope of the join points, while 'that' checks an object type. 
Sometimes this can be done statically (as in your case), but sometimes a 
run-time check must be generated.

The helper function access_A is needed to avoid cyclic access relations. If 
you have an <Aspect>.ah file and you want to access a class, from which your 
aspect is called, then you should have a separate <Aspect>.cc file, which 
includes the class header file. In the aspect header file there must be a 
forward declaration of the class.

I hope this helps,

Olaf


Olaf



More information about the aspectc-user mailing list