Managed Containers, Composites, and Aggregates

Value containers are containers of uniform (same-typed) values, for example, QString, byte, int, float, etc. Pointer containers are containers of pointers to (polymorphic commonly typed) objects. They can be managed or unmanaged.

Both kinds of containers can grow at runtime by allocating additional heap memory as needed. This is always done in an exception-safe way, so you don't need to worry about possible memory leaks.

In the case of pointer containers to heap objects, however, one must decide which class is responsible for managing the heap objects. UML diagrams can distinguish between managed and unmanaged containers by using composite (filled diamond) and aggregate (empty diamond) connectors, as shown in Figure 10.2.

Figure 10.2. Aggregates and compositions

In general, we can say that a managed container is a composite, because the container manages its pointed-to objects. In other words, when a composite is destroyed, it destroys (cleans up) its entire self (because the smaller objects are part of its composition).

When one object embeds another as a sub-object, it is also considered a composition.

In Figure 10.2, there are two kinds of Customer containers, CustomerList and CustDb. CustDb and CustomerList both reuse template containers. CustomerList objects are aggregatestemporary structures to hold the results of a query, or a user selection. CustDb, on the other hand, is a singleton composite that manages all of the Customer objects that exist.

In the case of the Customer and Address relationship, this diagram indicates that one or more Address objects should be associated with a particular Customer. When the Customer object is destroyed, it is reasonable to destroy all of its Address objects at the same time. Thus, the Customer object manages its Addresses, which gives us another example of a composite relationship.

This suggested design does impose some limitations on possible use of Address; in particular, there is no easy way to find all customers at a particular address. If Address and Customer were independently managed, then we could form bidirectional relationships between the classes.

Typically, a managed container deletes any heap objects it "owns" when the container itself is destroyed. With a Qt container of pointers, one can use qDeleteAll(container), an algorithm that calls delete on each element in the container.

Copying a managed container can be defined in a number of ways:

  • For some containers, the feature might be disabled.
  • For others, it might be called a deep copy, where all contained objects are cloned and placed in the new container.
  • Another approach, taken with the design of Qt containers, is implicit sharing, explained in the next section.

When a container only provides an indexing or reference navigation mechanism to its objects we call it an aggregate container.

In this case, the container does not manage its objects, it only provides a convenient way to access them. When an aggregate container is copied, only references to the collected objects are copied. When an aggregate container is deleted, only the references are removed. There is no impact on the underlying objects in the container.

A managed container is a composition, and an unmanaged container of objects is usually (but not always) represented in a UML diagram as aggregation.

 

Exercise: Managed Containers, Compositions and Aggregates

This exercise involves designing some data types to represent a deck and a hand of cards. The following UML diagram suggests one way of representing them.

Here are some hints:

  • The CardDeck constructor generates a complete deck of 52 cards in a convenient order.
  • CardDeck::deal(int k) should use the random() function from to pick k cards from the deck (removing each one from the deck after it is picked) to fill a CardHand object.
  • Initialize the random() function from the system clock so that the results will be different each time you run the app. The syntax is

    srandom(time(0));
  • Evaluate the hand using the rules of the game of bridge: Ace =4, King =3, Queen =2, Jack =1; all other cards have zero value. Use this formula to calculate the return values for the getValue() functions.
  • Example 10.6 gives a piece of client code that you can start with for testing.

    Example 10.6. src/cardgame/datastructure/cardgame-client.cpp

    #include "carddeck.h"
    #include 
    using namespace qstd; <-- 1
    
    int main() {
     CardDeck deck;
     CardHand hand;
     int handSize, playerScore, progScore;
     cout << "How many cards in a hand? " << flush;
     handSize = promptInt();
     do {
     hand = deck.deal(handSize);
     cout << "Here is your hand:" << endl;
     cout << hand.toString() << endl;
     playerScore = hand.getValue();
     cout << QString("Your score is: %1 points.")
     .arg(playerScore) << endl;
     // Now a hand for the dealer:
     hand = deck.deal(handSize);
     progScore = hand.getValue();
     cout << "Here is my hand:" << endl;
     cout << hand.toString() << endl;
     cout << QString("My score is: %1 points.")
     .arg(progScore) << endl;
     cout << QString("%1 win!!")
     .arg((playerScore > progScore)?"You":"I") << endl;
    
     } while(more("hand"));
    }
    
     

    (1)for cout, endl, and more()


Part I: Introduction to C++ and Qt 4

C++ Introduction

Classes

Introduction to Qt

Lists

Functions

Inheritance and Polymorphism

Part II: Higher-Level Programming

Libraries

Introduction to Design Patterns

QObject

Generics and Containers

Qt GUI Widgets

Concurrency

Validation and Regular Expressions

Parsing XML

Meta Objects, Properties, and Reflective Programming

More Design Patterns

Models and Views

Qt SQL Classes

Part III: C++ Language Reference

Types and Expressions

Scope and Storage Class

Statements and Control Structures

Memory Access

Chapter Summary

Inheritance in Detail

Miscellaneous Topics

Part IV: Programming Assignments

MP3 Jukebox Assignments

Part V: Appendices

MP3 Jukebox Assignments

Bibliography

MP3 Jukebox Assignments



An Introduction to Design Patterns in C++ with Qt 4
An Introduction to Design Patterns in C++ with Qt 4
ISBN: 0131879057
EAN: 2147483647
Year: 2004
Pages: 268

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net