Aggregation (Composition) of Classes

Making new classes from previous ones

Implicit functionality of aggregated classes

Constructors

Destructors

Copy Constructors

Assignment Operators

Example: Movie class

                        Movie.h

class Movie
{
    public:
                Movie ( );       // Constructors
                Movie ( string title_parameter );
                Movie ( string title_parameter, int n_stars );

                Movie ( const Movie& rhs);    // Copy constructor

                ~Movie ( );    // Destructor

                Movie& operator = ( const Movie& rhs );    // Overload =
                friend ostream& operator << ( ostream&, const Movie& ); // Overload <<
                // Can't be a member function, since lhs is ostream, not Movie

                string GetTitle (  ) const;
                string GetStar ( int index = 0 ) const;
                int GetID ( ) const;

                void SetTitle ( string title_parameter );
                void SetStar ( string name, int index );
                // No SetID (  ); handled by static field below

    private:
                string title;
                string* stars;
                int num_stars;
                int ID;
                static int nextID;
}

           Movie.cpp

int Movie :: nextID = 1; // No assignments possible within class definition

        Two possible parameterless constructors:

Movie :: Movie ( )
{
    ID = nextID ++;
    stars = 0;  // converts to NULL pointer
    num_stars = 0;

    // Default string constructor called: title is empty string   
}
                OR

Movie :: Movie ( ) : title ( "No title" )
{
    ID = nextID ++;
    stars = 0;
    num_stars = 0;

    // Could also have said: title = string("No title"); in constructor body
}
               

Movie :: Movie ( string title_parameter ) : title ( title_parameter )
{
   ID = nextID ++;
   stars = 0;
   num_stars = 0;
}

Movie :: Movie ( string title_parameter, int n_stars ) : title ( title_parameter )
{
    ID = nextID ++;
    num_stars = n_stars;
    stars = new string [ n_stars ];

    if ( stars == 0 ) // Not enough memory
        exit ( 1 );  // Could also throw an exception
}

Movie :: Movie ( const Movie& rhs ) : title ( rhs.title )
{
    ID = rhs.ID;
    num_stars = rhs.num_stars;
    stars = new string [ num_stars ]; // Default constructor used here for each string

    if ( stars == 0 )
        exit ( 1 );     // Could also throw an exception

    for ( int i=0; i < num_stars; i++)
        stars [ i ] = rhs.stars [ i ]; // Overloaded = used here for each string
}

Movie :: ~Movie ( )
{
    delete [ ] stars;  // Has no effect on NULL pointers

    // string destructor will be called on title and each element of stars array
}

string Movie :: GetTitle ( ) const
{
    return title;
}

string GetStar ( int index ) const
{
    if ( 0 <= index && index < num_stars )
        return stars [ index ];

    return string("Error: index out of range."); // Explicit constructor call
    // Could also throw an exception
}

int Movie :: GetID ( ) const
{
    return ID;
}

void Movie :: SetTitle ( string title_parameter )
{
    title = title_parameter;  // overloaded string assignment used
}

void Movie :: SetStar ( string title_parameter, int index )
{
    if ( 0 <= index && index < num_stars )
        stars [ index ] = title_parameter;

    // Could throw an exception if index out of range
}

Movie& Movie :: operator = ( const Movie& rhs )
{
    if ( this != &rhs )  // Don't clobber on self-assignment
    {
       ID = rhs.ID;
       num_stars = rhs.num_stars;
       title = rhs.title;       // Assignment operator for string used here

       delete [ ] stars;
       stars = new string [ num_stars ] ; // Default constructor for each string used here
       if ( stars == 0 )
            num_stars = 0;  // Or could throw an exception
    }

    return *this;
}

ostream& operator << ( ostream& out, const Movie& rhs )
{
    out << "Title: " << rhs.title << endl;

    out << "Stars: " << endl;
    for ( int i = 0; i < rhs.num_stars; i++ )
        out << rhs.stars[ i ] << " ";   // String class has also overloaded <<

    return out;
}