Gary Wessle said:
what is the difference "in code writing" between aggregation and
composition?
is the following correct?
aggregation (life time of both objects are independent).
class A{ /* ... */ };
class B{ A& a; /* ... */};
composition (b controls the life time of a)
class A{ /* ... */ };
class B{ A a; /* ... */};
I am not sure.
can some one please give some examples or even a link?
You could ask in the newsgroup comp.object.
When discussing the difference between aggregation and composition in
UML one has to keep in mind that UML is supposed to be independent of
any implementation language, so whatever the difference between the two,
it cannot be expressed in a manner that only one language can support.
C++ is unique among OO languages in its requirement to explicitly
destroy objects, so it's a safe bet that the difference between the two
associations has nothing to do with "who calls the destructor."
So, what is the difference? In a composition relationship, the whole has
sole responsibility for the disposition of its parts, or as you put it
above, the whole "controls the lifetime of" the part.
In other OO languages, if the whole shares its part with others, it
cannot guarantee that the part will be destroyed when the whole wants it
destroyed. In C++ if the whole shares its parts with others, it cannot
call the part's destructor without worrying that some object somewhere
has a reference/pointer to that part. Therefore, in order for the whole
to have "sole disposition" or "control the lifetime" of its parts, the
whole must be the only object that knows of the parts existence.
The only way to directly express this in C++ code, is to (a) not expose
the part object in the whole's interface or (b) if such exposure exists,
the part is passed using an auto_ptr. However, such expression isn't
necessary.
composition:
class Whole {
Part part;
public:
// no function returns 'part' as a Part& or Part*
// or if one does, the documentation explicitly states
// that the caller may not maintain a pointer/reference
// to the part.
};
or
class Whole {
Part* part;
public:
Whole(): part( 0 ) { }
~Whole() { delete part; }
void acceptPart( Part* part ) {
// documentation explicitly states that when the part
// is passed in, all other objects must relinquish any
// hold they have on the part.
}
};