[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