Composition

Discussion in 'C++' started by Denis Remezov, Apr 21, 2004.

  1. fog wrote:
    >
    > Given:
    >
    > class A;
    >
    > and B "has-a" A. The composition relationship between A and B can be
    > implemented in three ways:

    [snip]

    As Claudio remarked, #1 is composition, #2 is not; #3, well, #3 still
    can model composition, and in many cases, technically, it's the only way
    to go. It's just not required to necessarily represent composition.

    > Which method is better design?


    It depends on what you need to do.

    #1: B makes copies of components A or constructs new ones, who will die
    just before itself. If this is the exact intent, then #1 is the right
    choice. Class A must be a complete type at the point of definition of B.
    You may want to avoid this scheme if, e.g., objects A exist elsewhere,
    get cloned just for the purpose of becoming components of B, and are big
    and expensive to copy. A's lifetime coincides (up to the finer details of construction/destruction)
    with that of its host B.

    #2: Components A must be created elsewhere. B should require a guarantee
    that A doesn't get destructed prematurely, or some form of mechanism to
    ensure that (e.g. reference counting). Type A can be incomplete where
    B is defined. Components A cannot be re-assigned or re-created. Objects
    of B cannot be default-constructed. A is created before B and should live
    longer or at least as long. It can be shared between multiple objects
    of B.

    #3: The most general scheme, it can model #1 but at the cost of the
    inconveience of a pointer and overhead of manual handling/freestore
    allocation. It can imitate #2 with a slight syntactic difference.
    If #1 or #2 fit you perfectly then use them.
    Use this one if you need more choices:
    B and A can be coupled quite loosely, their lifetimes can overlap in any
    combination. Components A can be destructed, re-assigned or re-created.
    They can be shared between multiple objects of B. B can be default
    constructed. As in #2, you need to make sure component A is valid for
    as long as B is using it. Type A can be incomplete where B is defined.
    It can also be a polymorphic base class, e.g. an abstract class, with
    all possibilities that are unavailable in #1.

    Denis
    Denis Remezov, Apr 21, 2004
    #1
    1. Advertising

  2. Denis Remezov wrote:
    >

    [snips]

    >
    > #1: B makes copies of components A or constructs new ones, who will die
    > just before itself.


    Oops, that should read "just after".

    [snips]

    Denis
    Denis Remezov, Apr 21, 2004
    #2
    1. Advertising

  3. Denis Remezov

    fog Guest

    Given:

    class A;

    and B "has-a" A. The composition relationship between A and B can be
    implemented in three ways:
    ===================
    # 1.
    class B
    {
    A a;
    };
    ====================
    # 2.
    A a1;
    class B
    {
    A& a;
    };
    ====================
    # 3.

    class B
    {
    A* a;
    public:
    B(A* a1) : a(a1) { }
    };

    main()
    {
    A a;
    B b(&a);
    ....
    }
    =====================
    How to implement #2, specifically to initialize "A& a"?
    Which method is better design?
    Thanks for your help!
    fog, Apr 21, 2004
    #3
  4. Denis Remezov

    Sharad Kala Guest

    "fog" <> wrote in message
    news:dEohc.5542$...

    [snip]
    > =====================
    > How to implement #2, specifically to initialize "A& a"?


    B(A& o):a(o){
    }

    > Which method is better design?


    Depends on what you want.
    If the member could point to different A objects then A* should be used.
    If you know it's going to refer to the same A object then A&.
    You don't want to deal with pointers/references then use A, but then class A
    should be fully defined and each B object has _atleast_ the size of an A object.

    -Sharad
    Sharad Kala, Apr 21, 2004
    #4
  5. "fog" <> wrote
    > Given:
    >
    > class A;
    >
    > and B "has-a" A. The composition relationship between A and B can be
    > implemented in three ways:
    > ===================
    > # 1.
    > class B
    > {
    > A a;
    > };


    This is composition.

    > ====================
    > # 2.
    > A a1;
    > class B
    > {
    > A& a;
    > };


    This is NOT composition. You're simply referencing an external object.
    > ====================
    > # 3.
    >
    > class B
    > {
    > A* a;
    > public:
    > B(A* a1) : a(a1) { }
    > };


    Same as # 2. This is NOT composition. You're simply referencing an external
    object.

    >
    > main()
    > {
    > A a;
    > B b(&a);
    > ...
    > }
    > =====================
    > How to implement #2, specifically to initialize "A& a"?
    > Which method is better design?


    It's not a matter of "better". Only #1 models composition, so the other two
    examples are meaningless in this context.

    Claudio Puviani
    Claudio Puviani, Apr 21, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Schutkeker

    Need Composition Editor Tutorial

    John Schutkeker, Oct 17, 2003, in forum: Java
    Replies:
    0
    Views:
    316
    John Schutkeker
    Oct 17, 2003
  2. Rick Osborn

    Aggregation vs. composition

    Rick Osborn, Jan 23, 2004, in forum: Java
    Replies:
    11
    Views:
    57,907
    amitg_amity
    Aug 31, 2009
  3. -
    Replies:
    1
    Views:
    470
    John C. Bollinger
    Apr 11, 2005
  4. -
    Replies:
    3
    Views:
    323
  5. Roedy Green
    Replies:
    0
    Views:
    377
    Roedy Green
    Feb 4, 2006
Loading...

Share This Page