[aspectc-user] recognizing different object of the same class

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Fri Feb 4 22:37:18 CET 2005


Hello Hans,

Hans VB wrote:

> Hello,
>
> for my project I need to differentiate between 2 objects of a class, 
> say class Collection, objects CollectionA and CollectionB.
> I do this by keeping a vector in my aspect which holds the addresses 
> of the Collection-objects and later comparing these addresses with the 
> current address of a method call, say add().
>
> aspect LoggingAspect {
> private:
>    pointcut collectionConstruction()=construction("Collection");
>    pointcut collectionAdd()=execution("% Collection::add(...)");
>    vector<Collection*> usedCollections;
> public:
>    advice collectionConstruction() : after() {
>       usedCollections.push_back( tjp->that() );
>    }
>    advice collectionAdd() : after() {
>       int i=0;
>       while( tjp->that() != usedCollections[i]) { i++ };
>       cout << i << "th collection performed an add" << endl;
>    }
> }
>
> The biggest disadvantage of this is I can't get the names of the real 
> objects (e.g. CollectionA, CollectionB, ...), I only have a number 
> (the order in which the collections were constructed) to distinguish 
> between them.
> My question is if it is überhaupt possible to get these names now, or 
> in some future version of AspectC++. Maybe I'm missing some AC++ 
> constructs that would be more appropriate here ? Any ideas greatly 
> appreciated!
>
> Greets,
> Hans

you can avoid the vector by storing the object ID in the collection 
objects by using an introduction. Here is an extended version of your 
Trace aspect:

aspect Trace {
    ofstream out;
    pointcut to_trace () = execution ("% main(...)");
    advice to_trace () : around () {
        out << "before " << JoinPoint::signature () << endl;
        tjp->proceed ();
        out << "after " << JoinPoint::signature () << endl;
    }
    pointcut collection() = "Collection";
    pointcut collectionAdd()=execution("% %::add(...)") && 
within(collection());
public:
    advice collection() : int _trace_obj_id;
    advice construction(collection()) : after() {
        static int count = 0;
        tjp->that ()->_trace_obj_id = ++count;
    }
    advice collectionAdd() : after() {
        cout << tjp->that ()->_trace_obj_id
             << "th collection performed an add" << endl;
   }
    Trace () : out ("logfile2") {}
};

If an introduction is too invasive for you, you have to implement an 
external mapping (like your vector).

Getting the object name as context information is currently not 
possible. The reason is that the construction join points are lexically 
located in the class definition (where you find ordinary constructors). 
You also have to consider that dynamically created objects (as in "new 
Collection") don't have a name.

For the future I could imagine several join point types, which cover the 
numerous ways of creating objects in C++. They would complement 
construction advice as call advice complements execution advice. If, for 
instance, such join point would be the creation of a local variable, we 
could have the name as context information at this point. By using a 
cflow that passes this context information to the construction advice 
you would get what you want.

The first step on this road is the implementation of cflows with context 
variables, which is already on the development road map.

Regards,

Olaf




More information about the aspectc-user mailing list