[aspectc-user] syntax question
Law, Colin
colin.law at epid.eurotherm.co.uk
Tue Feb 12 12:57:15 CET 2002
> -----Original Message-----
> From: Olaf Spinczyk [mailto:olaf at ivs.cs.uni-magdeburg.de]
> Sent: 12 February 2002 10:31
> To: aspectc-user at aspectc.org
> Subject: Re: [aspectc-user] syntax question
>
>
> 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
Excellent, that works well (or should I say that(aptr) works well).
I am having a little trouble getting the hang of the syntax, in the line
advice that(aptr) && execution ("void %::a()"): void before(A *aptr)
presumably 'that()' is getting its parameter from 'before(A* aptr)', which
does not seem intuitive.
I attempted to get the same effect using a pointcut declaration as follows,
using my class types
pointcut ini() = that( "CWnd" ) && execution("int %::OnInitDialog()");
advice ini() : void before( CWnd* pWnd ) {...}
I did not have all that much hope that I had got it right, but it compiled
in ac++ but generated uncompilable code, with
TestAspect::aspectOf ()->TestAspect::__advice_0 ();
appearing in the new OnInitDialog(), but
void __advice_0( CWnd* pWnd )
appearing in the aspect declaration.
On the requirement for the helper function access_A, I tried it without the
helper function, directly accessing the pointer in before() and it was OK.
Can you explain this issue in more detail?
Thanks for all the help, I hope you are finding my input useful also.
Colin Law
More information about the aspectc-user
mailing list