Re: Aggregation vs composition

From: Matthias Hofmann (hofmann_at_anvil-soft.com)
Date: 04/28/04


Date: Wed, 28 Apr 2004 18:22:48 +0200


Daniel T. <postmaster@eathlink.net> schrieb in im Newsbeitrag:
postmaster-D42B22.08264728042004@news1.west.earthlink.net...

[...]

> > Obviously your concern is the problem of dangling references and wild
> > pointers, which is indeed something a programmer has to be aware of.
> > Nevertheless, holding a reference does not mean *controlling* lifetime,
it
> > rather means *depending on* lifetime. In your A-B-C example, the C
object is
> > NOT responsible for the disposition of the B object.
>
> This is the very statement which I am in disagreement with. If a
> particular B object is being held by both an A object and a C object,
> then they share the lifetime responsibility, they must cooperate with
> eachother in order for the B object to be destroyed. Let's diagram this
> another way, on the left we have "the set of all objects holding a
> reference to B's" (I'll call it X):
>
> [X]<#>--->[B]
>
> No obviously, both A and C belong to this set...

No, it is not obvious that A and C belong to this set. You have introduced a
new class and removed two other ones. As long as nothing else is shown, the
diagram only says that B's lifetime depends on X and that B is a part of X
that cannot be shared by other wholes.

> > If any of the clients refuses, then its his own fault, as he will end up
> > with a dead reference. A is not asking for permission to destroy B, it
> > merely informs C that B is about to go up in smoke, no matter wether C
wants
> > or not.
>
> This is only true in C++. If Composition only applies if the system is
> implemented in C++, I would agree with you. However, UML is supposed to
> be language neutral.

Maybe the concept of composition only applies to C++, and I remember having
read something like that on the internet. However, I do not know Java so I
cannot tell you for sure.

But this is just the very reason why the UML is language neutral. It shows
the union of capabilities of all (or better say many) programming languages,
not just the small intersection that these languages share. Or are you
asking to remove a feature from the UML just because Java can't handle it?

> > > Is it because (as someone has already said) that there
> > > is a line "delete child;" somewhere in the class? I dare say that that
> > > line exists *somewhere* or you have a leak. That would mean that *all*
> > > objects have a Containment relationship with *something*. The
> >
> > No, you only need to delete objects that are allocated dynamically. Use
a
> > regular data member and you have composition also:
> >
> > class Part {};
> >
> > class Whole
> > {
> > Part part;
> > };
>
> And woe be the code that allows a Whole to go out of scope, if it's part
> is shared with something else. What class is in charge of insuring that?
> That is where the true lifetime responsibility lies... If you say that
> no class has this responsibility? Then I must counter, "then the entire
> system has that responsibility" and that is a very sorry state to be in.
>

Indeed many good text books on C++ advice the reader not to return handles
to class-internal data, as this violates the priciples of encapsulation and
abstraction. However, if there is a certain requirement to do so, why
shouldn't the UML be able to show such a situation? If you consider it a bad
idea, the UML does not force you to do such things.

Besides, there are ways to implement your original A-B-C example without
running the risk of dead references. See the following code, which is a
modification of the one from my previous post:

class C
{
public:
    char* GetMessage()
    {
        return "Hello";
    }
};

class B
{
public:
    void SaySomething( const char* message )
    {
        std::cout << message << std::endl;
    }
};

class A
{
public:
    void Receive( const C& c )
    {
        b.SaySomething( c.GetMessage() );
    }

private:
    B b;
};

I think this corresponds with the diagram

|A|<#>------|B|<---------|C|

and there is no risk of B going out of scope before C wants this to happen.
I have to admit that there is no aggregation between B and C, so C does no
hold a reference to B, but in your example, C only sends a message to B. If
you want to hold a reference, you need to find another way to make sure that
B does not go out of scope too early.

> > Reference counting not always present. Objects do not always keep track
of
> > how many other objects hold references to them. Often, it is a matter of
> > timing - you usually know when an object goes out of scope, as the rules
on
> > that are very clear (at least in C++). You simply don't use an object
after
> > it has been destroyed.
>
> When objects are shared, reference counting is *always* present, even if
> only in the programmers head. At the very least, the programmer must
> know that at every point in the code where an object goes out of scope,
> there is only one other object holding a reference to it. He can't
> guess, wonder or hope, he must know.

I don't know what you mean by "...there is only one other object holding a
reference to it." All that a programmer must know when an object goes out of
scope is, that the object is gone from that moment and that it must not be
used any more. In practice, I have never experienced this to be a problem.

Best regards,

Matthias



Relevant Pages

  • Re: Interview Questions
    ... > would wirelessly access the internet during an exam to find answers to ... required to answer the questions is necessary to be known without reference ... That eliminates from qualifying test ... IBM used to use a "Programmer Apptitude Test" in the '60s which I believe ...
    (comp.lang.cpp)
  • Re: Are programmers like this in the real world?
    ... >> nobody other than the insurance carriers. ... > gone, programmer, although lack of company QA also played a big role. ... Anytime one person has responsibility for code that can kill someone, ... > that when medicine and law were infant industries, ...
    (comp.programming)
  • Re: Multi Dimensional Array Reallocation ?
    ... Compile time binding eliminates the need for ... >>> instance types on each reference, and the need to store class symbol ... >> It would free the programmer from these stinking limitations where the ... It makes much more sense to fit a design to the language. ...
    (alt.comp.lang.borland-delphi)
  • Re: Intro to Programming w/ Machine Language
    ... > responsibility to make your software available within a reasonable time. ... The issue isn't performance, per se, it is the total amount of wasted ... And if the programmer *has* done this from the beginning, ... > the deadline, and the managers job to always enforce the deadline. ...
    (comp.programming)
  • Re: Intro to Programming w/ Machine Language
    ... > responsibility to make your software available within a reasonable time. ... The issue isn't performance, per se, it is the total amount of wasted ... And if the programmer *has* done this from the beginning, ... > the deadline, and the managers job to always enforce the deadline. ...
    (alt.lang.asm)

Loading