1. Modeling the Association Relationship in the Object Model

In the previous chapters we discussed how to model classes and objects. The purpose of this chapter is to describe how to model relationships between classes and between objects in the object model. The object model is the structure and description of classes, objects, and relationships in a system. The basic topics are:

What is a relationship?

What is an association relationship?

How to identify association relationships.

How to show association relationships on a class diagram.

How to specify an association relationship including constraints.

How to generate C++ with a CASE tool script for relationships.

  1. What is a Relationship?

A relationship is a link or connection between classes or between objects. There are four major O-O relationships: association ("has a), aggregation ("part of"), generalization specialization ("is a"), and interaction ("calls"). Association, aggregation, and association relationships are identified in the object model. Interaction relationships are identified in the dynamic model. In the physical world we see these relationships all the time. Several physical real world examples of relationships are shown in the table below.

Table of physical, real world examples of relationships.

------------------------------------------------------------------------------

Example Relationship

------------------------------------------------------------------------------

A driver "has a" car. Association

The car "has a part" a motor. Aggregation

The car "is a" vehicle. Generalization specialization

A driver "interacts" with a car. Interaction

A house "has" furniture. Association

A house "has a part" roof. Aggregation

A house "is a" physical structure. Generalization specialization

An owner "interacts" with a house Interaction

------------------------------------------------------------------------------

In software information systems we also see these relationships. Several software, information systems examples of relationships in the table below.

Table of software, information systems examples of relationships.

--------------------------------------------------------------------------------------------------

Example Relationship

--------------------------------------------------------------------------------------------------

An invoice "has a" salesman Association

An invoice "has a part" item list Aggregation

An invoice "is a" retail document Generalization specialization

A user "interacts with" (updates) an invoice Interaction

A library book loan "has a" borrower Association

A library book loan "has a" due date Aggregation

A library book loan "is a" library document Generalization specialization

A librarian "interacts with" (updates) a library book loan Interaction

----------------------------------------------------------------------------------------------------

A major relationship is association. In this section we will look at association, the "has a" connection. We will look at "what is association?", how to identify association, how to show association on a class diagram, how to specify association, and how to code association.

  1. Showing Relationships on the Class Diagram

The class diagram is a graphic representation of classes and relationships. Using the Rumbaugh OMT notation we show association (has a), aggregation (part of) relationship, and generalization specialization (is a) relationships on the class diagram. We show the interaction (calls) relationship, e.g. events and messages on the object interaction diagram to be presented in a later section. The class diagram below shows the major relationships and cardinalities of generalization specialization (Vehicle to Car), 1 to 1 aggregation (Car to Motor), 1 to many aggregation (Car to Tire), 1 to zero or one association (Car to CellularPhone), and 1 to many association (Car to Passenger). The diagram shows traversal path names for the association and aggregation relationships. A traversal path name is a reference to one or more associated or part objects. In the class diagram below, the traversal path names are currentMotor, currentTires, currentCellularPhone, and currentPassengers. The traversal path names are important to be able to access an associated or part object. For example, the car1 object accesses the cellularPhone1 object through the traversal path "currentCellularPhone".

Figure Class diagram showing relationships in the Car Simulation System
  1. Creating Relationship Specifications and Reports

Each relationship should be described in a relationship specification form. Its purpose is to state adequate information to document and to program each relationship. We will first present a sample specification input form, define the specification information, and present a sample report. The steps to create the class specification using a CASE tool or text editor are listed below.

>> Run the CASE tool or text editor from Windows

>> Select "File - Open" e.g. c:\car.omt

>> Double click on a relationship, e.g. currentMotor

>> Enter the relationship information

>> Select "Generate - Generate Class Report" and select a report script, e.g. RPTRELAT.SCT

>> Select "File - Edit File" and enter the report name to view the report.

  1. Relationship Specification Input Form

The following is a sample relationship specification form created in a text editor. Some CASE tools collect relationship specification information directly from the class diagram and do not offer the relationship specification. If you desire to collect specification information, you may use a text editor to collect the following information.

Source Class - Car

Destination Class - Motor

Traversal Path Class/Type and Name - Car currentMotor

Order by Attribute Class/Type and Name - N/A

Type of Relationship (Association/Aggregation) - Aggregation

Relationship Constraints (rules) - A car must have a motor

Relationship Cardinality - 1 to 1

Inverse Traversal Path Class/Type and Name - Car currentCar

Implementation - C++ data member

Remarks - N/A.

Figure Sample Relationship Specification Input Form for a Use with a Text Editor

  1. Relationship Specification Information

The relationship specification holds information on each relationship. Relationship information includes the following:

- Source Class states initial class to define the relationship.

- Destination Class states the second class to define the relationship.

- Traversal Path Class/Type and Name states the class/type and name of the attribute which implements the relationship and which is used to traverse (get) an object of the associated or part class.

- Order by Attribute Class/Type and Name states the class/type and name of the attribute which orders the objects of the associated or part class.

- Type of Relationship (Association/Aggregation) states the type of relationship, e.g. association or aggregation.

- Relationship Constraints states rules or expressions that restrict or constrain a relationship such as a motor weight must be less car frame weight.

- Relationship Cardinality states the relationship cardinality, e.g. 1 to 1, 1 to 0 or 1, 1 to many, or many to many

- Inverse Traversal Attribute Class/Type and Name states class/type and name of the inverse traversal path.

- Implementation states the language dependent implementation of the relationship, e.g. a Motor data member implements the aggregation relationship between Car class and Motor class.

- Remarks states any additional information about the relationship.

  1. Relationship Specification CASE Tool Script Variables

To access the relationship specification information, you need to know the script variable for each piece of information in the class diagram or relationship specification input form. The following are sample script variables from the relationship specification in a CASE tool. This CASE tool only collects only the relationship path and class names. A brief description states what occurs when the script variable appears in a script. Relationship variables access relationship information. Since there are multiple relationship for each class, these variables are used within the [] (Repeat Operator). For example, the following script statement prints out the association relationship names for each class [ASSOCIATION_ONE_NAME, ].

BASE_CLASS or SUPERCLASS_NAME Prints superclass name for a class

ASSOCIATION_ONE_CLASS Prints class name for a 1 to 1 association

ASSOCIATION_ONE_NAME Prints traversal path name for a 1 to 1 association

ASSOCIATION_MANY_CLASS Prints class name for a 1 to M association

ASSOCIATION_MANY_NAME Prints traversal path name for a 1 to M association

AGGREGATION_NAME Prints traversal path name for aggregation (part) class

AGGREGATION_ONE_CLASS Prints class name for a 1 to 1 aggregation

AGGREGATION_ONE_NAME Prints traversal path name for a 1 to 1 aggregation

AGGREGATION_MANY_CLASS Prints class name for a 1 to M aggregation

AGGREGATION_MANY_NAME Prints traversal path name for a 1 to M aggregation

  1. Relationship Specification Report and Script

CASE tools collect minimum relationship information, such as the source class, destination class, and traversal path name. A relationship report detailing each relationship may be created. The following is a sample report and table showing relationship information for the Car Simulation System was created with a CASE tool.

Relationship Specification Report

Class : Car

Superclasses: Vehicle

Library Superclass:

Associated Class - Traversal Name: CellularPhone - currentCellularPhone

Associated Class - Traversal Name: Passenger - currentPassengers

Part Class - Traversal Name: Motor - currentMotor

Part Class - Traversal Name: Tire - currentTires

The script (RPTRELAT.SCT) to create this report is shown below.

Script to Generate the Relationship Report

Class : CLASS_NAME

Superclasses: [NO_RETURN BASE_CLASS ,DELETE_LAST_SYMBOL]

Library Superclass: CLASS_LIBRARY_BASE_CLASS

[Associated Class - Traversal Name: ASSOCIATION_ONE_CLASS - ASSOCIATION_ONE_NAME]

[Associated Class - Traversal Name: ASSOCIATION_MANY_CLASS - ASSOCIATION_MANY_NAME]

[Part Class - Traversal Name: AGGREGATION_ONE_CLASS - AGGREGATION_ONE_NAME]

[Part Class - Traversal Name: AGGREGATION_MANY_CLASS - AGGREGATION_MANY_NAME]

  1. Relationship Table and Script

The relationship table for the Car Simulation System is shown below.

Relationship Table

Source Class Destination ClassTraversal Path Name Relationship Description
VehicleCarN/A Generalization Specialization Vehicle to Car
CarCellularPhonecurrentCellularPhone 1:1 Association from Car to CellularPhone
CarPassengercurrentPassengers 1:M Association Car to Passenger
CarMotorcurrentMotor 1:1 Aggregation Car to Motor
CarTirecurrentTires 1:M Aggregation Car to Tire

The script (TABRELAT.SCT) to create this table from a class diagram is shown below.

Script to Generate the Relationship Table

SCRIPT_NOREPEAT_HEADER_BEGIN

Source Class, Destination Class, Traversal Path Name, Relationship Description

SCRIPT_NOREPEAT_HEADER_END

[SUPERCLASS_NAME, CLASS_NAME, N/A, Generalization Specialization SUPERCLASS_NAME to CLASS_NAME]

[CLASS_NAME, ASSOCIATION_ONE_CLASS, ASSOCIATION_ONE_NAME, 1:1 Association from CLASS_NAME to ASSOCIATION_ONE_CLASS]

[CLASS_NAME, ASSOCIATION_MANY_CLASS,ASSOCIATION_MANY_NAME, 1:M Association CLASS_NAME to ASSOCIATION_MANY_CLASS]

[CLASS_NAME, AGGREGATION_ONE_CLASS,AGGREGATION_ONE_NAME, 1:1 Aggregation CLASS_NAME to AGGREGATION_ONE_CLASS]

[CLASS_NAME, AGGREGATION_MANY_CLASS,AGGREGATION_MANY_NAME, 1:M Aggregation CLASS_NAME to AGGREGATION_MANY_CLASS]

  1. What is Association?

Association is a link between objects of two or more classes. An association exists between objects of different classes whenever there is a logical linking, interaction, or dependency between the objects. An association relationship may be described as "has a", "associated with" or "knows about". For example a car "has a" cellular phone as shown in the figure below.

Figure Drawing showing associations.

An association has a cardinality or multiplicity. This is the number of objects on one side of an association that may be associated with an object on the other side of the association. For example, one car has one cellular phone. This is an example of a 1 to 1 association. If a car object may have many passenger objects, then there is a 1 to many association between the car class and the passenger class.

An association and aggregation relationship have constraints. A constraint is a limitation, restriction, or rule. Multiplicity (cardinality) is a constraint. For example a constraint on the car to passenger association is that a car can only have 6 passengers. Constraints on each relationship may be specified in a relationship specification form with a CASE tool.

The association relationship is important for many reasons. Association is the most fundamental relationship of real world physical things and software entities. Association helps develop highly cohesive objects where all associated objects are linked to accomplish a purpose. It implements dependency among objects. For example, an object may be dependent upon its associated objects to accomplish its function. It implements visibility among objects. For example, an object has visibility for (sees) its associated objects so that it can send messages to its associated objects.

  1. Identifying Associations

Identify association by looking for logical links or connections between two or more objects. One object may "know about" another object. For example, a retail store "knows about" its employees. One object may "depend upon" another object. For example, a bank "depends upon" its tellers. Often it is useful to make a drawing of the key objects in a system and show the association between the objects on the drawing. For each object on the drawing, identify associations between them.

The following are suggested steps to identify association relationships:

Step 1. Make a drawing or physical representation, e.g., a car, a motor, a passenger.

Step 2. Identify the objects and their classes, e.g., a car, a motor, a passenger.

Step 3. For each object, identify association relationships with the question "For each object what are the associated objects?"

Step 4. Identify the multiplicity of each association relationship with the questions "This object is associated with zero, one or many of the other object?" and "This association is either optional or required?"

Step 5. Identify if the relationship is an association ("has a") or an aggregation ("part of"). When in doubt assume association ("has a").

Step 6. For each relationship, identify the constraints (limitations or rules).

Step 7. If available, check messages between objects in the dynamic model because messages indicate association and aggregation relationships.

Step 8. Create a class diagram, data dictionary, class specification, and prototype.

  1. Showing Association on the Class Diagram

Show association on a class diagram by connecting two or more classes together with the association symbol (a solid line). Some CASE tools show the name of the association relationship, such as "has a", or the name of the traversal path, such as currentCellularPhone. A traversal path name is a reference to one or more associated objects. In the class diagram below, the traversal path names are currentCellularPhone and currentPassengers. The open circle on the association line indicates an optional (zero or one) association. The black circle on the association line indicates many (zero or more) in the association. The figure below is an example of a class diagram showing association using a CASE tool.

Figure Class diagram showing association.

As shown in the figure below, the car class has an association with the cellular phone class. An object of the car class may have an association with zero or one objects of the cellular phone class. The label on the association line is the name of the traversal path name or the name of the association such as "has a". A traversal path name is a reference to one or more associated objects. In this case currentCellularPhone is the traversal path name that holds the object name of the associated cellular phone object. The car class has an operation "make phone call" and the cellular phone class has an operation "makePhoneCall".

As shown on this diagram, the car class has an association with the passenger class. An object of the car class may have an association with zero, one, or many objects of the passenger class. The car class has a traversal path name currentPassengers which holds the object names of associated passenger objects. The car class has the operations "add passenger" and "remove passenger".

The steps to create the class diagram showing association using a CASE tool are as follows:

>> Run the CASE tool and show the tool bar or pull down menu.

>> Select and place a class symbol for the first class.

>> Select and place a class symbol for the second class.

>> Select the association relationship symbol and the cardinality (1:1, 1:M, etc)

>> Connect the two classes.

>> For C++ code generation, enter a name for the traversal path name to represent the association.

  1. Specifying Association

Each association relationship should be described in a relationship specification form. Constraints (limitations and rules) should be stated. For association multiplicity constraints should be stated. For example, the following is a sample relationship specification report created in a text editor.

Relationship Specification Report

- Source Class - Car

- Destination Class - CellularPhone

- Traversal Path Class/Type and Name - Car currentCellularPhone

- Order by Attribute Class/Type and Name - N/A

- Type of Relationship (Association/Aggregation) - Association

- Relationship Constraints (rules) -

- Relationship Cardinality - 1 to 0/1

- Inverse Traversal Path Class/Type and Name - Car currentCar

- Implementation -

- Remarks.

  1. Coding Association in C++

There are several ways to code the 1 to 1 and 1 to Many associations in C++. These will be described in the following sections.

  1. Minimum C++ Code for 1 to 1 Association

Once the class diagram has been completed, then C++ code can be automatically generated with a CASE tool. The CASE tool implements each association shown on the class diagram. We are presenting how to code associations in C++ to be able to understand and modify the generated C++.

There are many ways to code association and aggregation in C++, such as coding data members to hold associated objects, pointers to associated objects, or objects of special association classes. The most straight forward way to code association is to identify a traversal path name. As previously stated, a traversal path name is a reference to one or more associated objects. A traversal path name is a data member that may hold one of the following: an associated object, a collection of associated objects, a pointer to an associated object, or a pointer to a collection of associated objects.

To code the association relationship, identify a traversal path name to represent the association. The traversal path name becomes a data member in one of the associated classes. In the simplest case, a car has 1 cellular phone. In the Car class identify a traversal path name for the 1 to 1 association with the cellular phone class. The traversal path name in the Car class might be CellularPhone *currentCellularPhone. In C++ code, create a data member for the traversal path name, such as currentCellularPhone as a pointer in the following form and example:

<Class Name of Associated Object> * <Traversal path name>;

CellularPhone *currentCellularPhone;

In this case the data member holds a pointer to the associated object. A pointer is used because an associated object can exist independently of the other associated object. When one associated object is deleted, then the other associated object is not deleted. For example, a cellular phone is not deleted when the car is deleted.

When we use a C++ pointer for 1 to 1 association, we must connect the declared pointer with an actual object. For example we must connect the cellularPhone1 object to the pointer *currentCellularPhone. We can do that with a constructor with arguments or an attach operation. The sample constructors and destructors below initialize the pointer to 0. Alternatively you may initialize the pointer to a null association object as shown in the code listing.:

Car () { currentCellularPhone = 0; } // default constructor

//to initialize currentCellularPhone pointer

Car (CellularPhone *aCellularPhone) //constructor with

{currentCellularPhone = aCellularPhone; }//argument to connect the associated object

~Car () {currentCellularPhone = 0;}//destructor to detach associated object

The following are sample invocations of these two constructors:

Car car1; //invokes the default constructor

Car car2 (&cellularPhone1) //invokes the constructor with arguments

An set or attach operation to attach an associated object in a 1:1 sets the traversal path name to be the associated object.

void setCellularPhone (CellularPhone &aPhone)

{ currentCellularPhone = &aPhone; }

The set or attach operation may receive the associated object, a pointer to the associated object, or a reference to the associated object. The benefit of a reference is that any changes to the associated object in the set operation will be reflected in the object itself.

The remove or detach operation to detach an associated objects sets the traversal path name to 0 or NULL in a 1 to 1 association. If required, the caller may have to delete the actual associated object if the object is a dynamic object created with the new keyword, e.g. delete cellularPhone1;

void removeCellularPhone (CellularPhone &aCellularPhone)

{ currentCellularPhone = 0; }

The getAssociatedObject operation returns the identity of the current associated object.

CellularPhone& getCellularPhone ()

{ return * currentCellularPhone; }

An example of association is shown in the figure below. There is a one to one association between an object of the car class and an object of the cellular phone class. The listing below is a the generated C++ code with added statements and an added main function.

Figure Class diagram showing a 1:1 association.

Listing C++ code listing showing 1 to 1 association.

C++ Minimum Class Declaration with 1 : 1 Association - Header Files

//////////////////////////Car.h file////////////////////////////////////

#ifndef __CAR_H

#define __CAR_H

#ifndef __CLLLRPHN_H

#include "ClllrPhn.h"

#endif

class Car

{ int speed; //Attribute data member

CellularPhone* currentCellularPhone; //1:1 association object data member

public:

Car () : speed(0)

{ currentCellularPhone = 0; //Initialization to 0

}

//Get accessor function for 1:1 association object data member

const CellularPhone* getCellularPhone() const

{ return currentCellularPhone;

}

//Set accessor function for 1:1 association object data member

void setCellularPhone (CellularPhone* const acurrentCellularPhone)

{ currentCellularPhone = acurrentCellularPhone;

}

//Remove function for 1:1 association object data member

//Warning delete currentCellularPhone object if dynamic object

void removeCellularPhone()

{ currentCellularPhone = 0;

}

void makePhoneCall (long aNumber) ;

~ Car ( ) { } //Destructor

};

#endif

//////////////////////////ClllrPhn.h file////////////////////////////////////

#ifndef __CLLLRPHN_H

#define __CLLLRPHN_H

class CellularPhone

{ long phoneNumber; //Attribute data member

public:

CellularPhone () : phoneNumber(0)

{

}

void makePhoneCall (long aNumber) ;

~ CellularPhone ( ) { } //Destructor

};

#endif

C++ Source Code Files

//////////////////////////Car.cpp file////////////////////////////////////

#include "Car.h"

void Car::makePhoneCall(long aNumber) //Body added after code generation

{ if (currentCellularPhone == 0) return; //no cellular phone to make call

currentCellularPhone -> makePhoneCall (aNumber);

}

//////////////////////////ClllrPhn.cpp file////////////////////////////////////

#include "ClllrPhn.h"

void CellularPhone::makePhoneCall(long aNumber) {

}

C++ Main Function

//////////////////////////main.cpp file////////////////////////////////////

#include "Car.h"

int main ()

{

Car car1; //invokes the default constructor

CellularPhone cellularPhone1;

car1.setCellularPhone (&cellularPhone1);

car1.makePhoneCall (55555);

return 0;

}

In this example, the CASE tool generated the class declarations (.h files) for the car class and the cellular phone class. In the car class, it generated the include directives to include the files of the associated cellular phone class. In the car class, the CASE tool generated a private data member to implement the 1:1 association between car and cellular phone. The private data member is a pointer to an associated cellular phone object. It is a pointer because the associated cellular phone object has independent existence. A car object can be deleted without deleting the associated cellular phone object. The generated C++ code was updated to fill-in the function definitions and to provide a main function.

  1. Minimum C++ Code Generation Scripts for 1 : 1 Association

To generate the C++ class declaration and function definitions, we used two scripts. A class declaration script generated the Car.h file and function definition script generated the Car.cpp file. We created the main.cpp manually. The two scripts are shown below.

Script to Generate the C++ Minimum Class Declaration with 1 : 1 Association - Header File

//////////////////////////TRUNCATE_EIGHT$CLASS_NAME.h file////////////////////////////////////

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H

#define __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H

[

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$ASSOCIATION_ONE_CLASS$_H

#include "TRUNCATE_EIGHT$ASSOCIATION_ONE_CLASS.h"

#endif

]

class CLASS_NAME[NO_RETURN NO_REPEAT: NO_REPEAT public BASE_CLASS ,DELETE_LAST_SYMBOL]

{ [CPP_ATTRIBUTE_STATIC CPP_ATTRIBUTE_CONSTANT ATTRIBUTE_TYPE ATTRIBUTE_NAME$; //Attribute data member]

[ASSOCIATION_ONE_CLASS$* ASSOCIATION_ONE_NAME$; //1:1 association object data member]

public:

CLASS_NAME ()

SELECT_WHEN LOGICAL_NOT ATTRIBUTE_IS_STATIC [NO_RETURN NO_REPEAT: ATTRIBUTE_NAME(ATTRIBUTE_INITIAL_VALUE),DELETE_LAST_SYMBOL]

{ [ASSOCIATION_ONE_NAME = 0; //Initialization to 0 ]

}

[ //Get accessor function for 1:1 association object data member

const ASSOCIATION_ONE_CLASS$* get$ASSOCIATION_ONE_CLASS$() const

{ return ASSOCIATION_ONE_NAME$;

} ]

[ //Set accessor function for 1:1 association object data member

void set$ASSOCIATION_ONE_CLASS ($ASSOCIATION_ONE_CLASS$* const a$ASSOCIATION_ONE_NAME$)

{ ASSOCIATION_ONE_NAME = a$ASSOCIATION_ONE_NAME$;

} ]

[ //Remove function for 1:1 association object data member

//Warning delete ASSOCIATION_ONE_NAME object if dynamic object

void remove$ASSOCIATION_ONE_CLASS$()

{ ASSOCIATION_ONE_NAME = 0;

} ]

[ OPERATION_RETURN_TYPE OPERATION_NAME (CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL;

]

~ CLASS_NAME ( ) { } //Destructor

};

#endif

Script to Generate the C++ Function Definitions - .cpp File

//////////////////////////TRUNCATE_EIGHT$CLASS_NAME.cpp file////////////////////////////////////

#include "TRUNCATE_EIGHT$CLASS_NAME.h"

[

OPERATION_RETURN_TYPE CLASS_NAME::OPERATION_NAME(CPP_OPERATION_PARAMETERS)

{

OPERATION_CODE

}

]

  1. Enhanced C++ Code for 1 to 1 Association

To code C++ classes with 1 to 1 association, create a class declaration and function definitions as shown in the diagrams below. Key aspects of the class declaration are shown on the left. This information class diagram shows that a class declaration of the first class (class with association) should have an include statement for the association class file, a class name, data members, traversal data members holding a pointer to an object of the association class, a constructor, traversal function members to access an object of the association class, traversal data member accessor functions, function members, and a destructor. This information class diagram shows that the first class (class with association) is connected to the second class (association class) with the traversal data member. The traversal data member is used to access the object of the second class (association class). The class diagram on the right shows sample C++ identifiers that are also in the code listings.

Figure Class diagram showing 1 to 1 association

The following are key points about coding a class with an association. The class may or may not create and delete association objects.

- Declare a #include compiler directives to include the association class, e.g. #include "Cllrphn.h".

- Declare a pointer as an association object data member, e.g. CellularPhone *currentCellularPhone;

- Define a traversal function to access the association object data member, e.g. void makePhoneCall ()

- Define a default constructor to initialize an object with default data member values, e.g. Car (){currentCellularPhone = 0;} Set association data member pointers to 0 or to the address of a null association object. Actual association object must be assigned with a set statement, e.g. car1.setCellularPhone(&phone1);

- Define a constructor with arguments to initialize an object with passed values. Optionally, pass a pointer to an association object and assign the association object data member. Car (int aSpeed, CellularPhone* currentCellularPhone) : speed (aSpeed), currentCellularPhone (aCellularPhone) { }

- Define a copy constructor to initialize a object with a copy of another object. Optionally, assign the association object data member to the association object in the copy or create a new association object. Car (const Car& aCar) { currentCellularPhone = aCar.currentCellularPhone; }

- Define an assignment operator (operator=) to assign one object to another. Optionally, assign the association object data member to the association object in the copy or create a new association object. Car& operator= (const Car& aCar) {currentCellularPhone = aCar.currentCellularPhone ; }.

- Define an equality operator (operator==) to compare two objects. Optionally, compare the association object data members, e.g. int operator== (const Car& aCar) { return (currentCellularPhone == aCar.currentCellularPhone ) ; }. Note - the two objects equal only if they both point to the same association object. The alternative is not to compare the associated object data members.

- Define input function - C++ insertion operator for use with cin. Optionally, invoke the association object operator>>, e.g. friend istream& operator>> (istream& is, Car& aCar) {is >> *aCar.currentCellularPhone; }

- Define the output function - C++ extraction operator for use with cout. Optionally, invoke the association object operator<<, e.g. friend ostream& operator<< (ostream& os, Car& aCar) { os << * aCar.currentCellularPhone; }

- Define get, set, remove, exists, and exists (a specific object) assessor functions, e.g. CellularPhone* getCellularPhone () { return currentCellularPhone; }. Warning returning a pointer provides direct access to a private data member.

- Define a default destructor to deinitialize an object, ~Car () {}

- Define a main (test) function to create an object with an association object and invoke a traversal function

In the association class, optionally declare an inverse traversal data member, e.g. Car * aCar; Prior to compiling the class, insert a forward declaration before the class declaration, e.g. class Car; The complete C++ code listing is below.

Listing C++ Code Listing for 1 to 1 Association

C++ Class Declaration with 1 : 1 Association - Header File

// Class: Car //ANSI C++

#ifndef __CAR_H //Required for Car class

#define __CAR_H

#ifndef __IOSTREAM_H //Required for cin and cout

#include <iostream.h>

#endif

#ifndef __CSTRING_H //Required for CString class

#include <CString.h>

#endif

//Required for 1:1 association classes

#ifndef __CLLLRPHN_H //CellularPhone

#include "ClllrPhn.h"

#endif

class Car

{ int speed; //Attribute data member

CellularPhone* currentCellularPhone; //1:1 association object data member

CellularPhone nullCellularPhone;//Null association object for association object

public:

//Default constructor alternative to compiler provided default constructor

//Association object data member pointers initialized to null association object

Car ();

Car ( int aspeed ) ; //Constructor with arguments

Car (const Car& aCar ); //Copy Constructor

Car& operator= (const Car& aCar); //Operator= Assignment Operator

int operator== (const Car& aCar) const; //Operator== Equality Operator

friend ostream& operator<< (ostream& os, const Car& aCar); //Operator<< for cout

friend istream& operator>> (istream& is, Car& aCar); //Operator>> for cin

int getspeed() const//Get accessor function for non-static attribute data member

{ return speed;

}

//Set accessor function for non-static attribute data member

void setspeed (const int aspeed)

{ speed = aspeed;

}

//Get accessor function for 1:1 association object data member

const CellularPhone* getCellularPhone() const

{ return currentCellularPhone;

}

//Set accessor function for 1:1 association object data member

void setCellularPhone (CellularPhone* const acurrentCellularPhone)

{ currentCellularPhone = acurrentCellularPhone;

}

//Remove function for 1:1 association object data member

//Warning delete currentCellularPhone object if dynamic object

void removeCellularPhone(); //throw (string)

//Exists function for 1:1 association object data member

int existsCellularPhone() const;

//Exists function with argument for 1:1 association object data member

int existsCellularPhone (CellularPhone* const acurrentCellularPhone) const;

void makePhoneCall (long aNumber) ;

~ Car ( ) { }

//Destructor - Delete any pointer data members that used new in constructors

//Destructor should be virtual if and only if class contains at least one virtual

// function. Objects destroyed in the reverse order of the construction order

};

#endif

C++ Source Code File

//////////////////////Car.cpp file//////////////////////////////////////////////

#include "Car.h"

// Functions for class Car

void Car::makePhoneCall(long aNumber)

{

}

//Default constructor alternative to compiler provided default constructor

//Association object data member pointers initialized to null association object

Car::Car () : speed(0)

{ currentCellularPhone = &nullCellularPhone;

//Initialization to null association object

}

//Constructor with arguments

Car::Car ( int aspeed )

{ speed = aspeed; //Initialization of attributes

currentCellularPhone = &nullCellularPhone;

//Initialization to null association object

}

//Copy constructor alternative to compiler provided default copy constructor

Car::Car (const Car& aCar )

{speed = aCar.speed;

currentCellularPhone = &nullCellularPhone;

//Initialization to null association object

//currentCellularPhone = aCar.currentCellularPhone; //Commented out shallow copy

}

//Operator= Assignment Operator alternative to compiler provided operator=

Car& Car::operator= (const Car& aCar)

{ if (this == &aCar) return *this;

speed = aCar.speed;

currentCellularPhone = &nullCellularPhone;

//Initialization to null association object

// currentCellularPhone = aCar.currentCellularPhone;//Commented out shallow copy

return *this;

}

//Operator== Equality Operator

int Car::operator== (const Car& aCar) const

{ return (

//Equality check for 1:1 association data members for shallow comparison

//( currentCellularPhone == aCar.currentCellularPhone) &&

//Equality check for attribute data members

(speed == aCar.speed)

);

}

//Operator<< extraction for cout

ostream& operator<< (ostream& os, const Car& aCar)

{ os << "Object Attribute Values - Class Car" << endl;

os << "speed: " << aCar.speed << endl;

return os;

}

//Operator>> insertion for cin

istream& operator>> (istream& is, Car& aCar)

{ cout << "\nEnter Object Attribute Values or 0 - Class Car";

cout << "\nEnter speed : " << endl;

is >> aCar.speed;

if (aCar.currentCellularPhone != &aCar.nullCellularPhone) is >> *aCar.currentCellularPhone ;

return is;

}

//Remove function for 1:1 association object data member

//Warning delete currentCellularPhone object if dynamic object

void Car::removeCellularPhone() //throw (string)

{ string noCellularPhone;

if ( currentCellularPhone == &nullCellularPhone ) throw noCellularPhone;

else currentCellularPhone = &nullCellularPhone;

}

//Exists function for 1:1 association object data member

int Car::existsCellularPhone() const

{ if ( currentCellularPhone == &nullCellularPhone ) return 0; else return 1;

}

//Exists function with argument for 1:1 association object data member

int Car::existsCellularPhone (CellularPhone* const aCellularPhone) const

{ if ( currentCellularPhone == &nullCellularPhone ) return 0;

else if ( *currentCellularPhone == *aCellularPhone ) return 1;

else return 0;

}

  1. Minimum C++ Code for 1 to Many Association

In the 1 to many association identify a traversal path name that holds a collection of associated objects. For example, a car has many passengers. In the car class identify a traversal path name, such as passengerArray or aPassengerList. In C++ code, create a data member for the traversal path name, such as passengerArray or aPassengerList. The following are several examples:

Passenger *passengerArray[maxPassengers]; //C++ array

List <Passenger> aPassengerList; //C++ template class

A C++ template is a special generic structure that can be defined to hold objects of different classes. For example a generic list can be defined to hold passengers or to hold items of fruit.

It is the programmer's responsibility to add and remove associated objects from the collection of associated objects. For example, the programmer must insert passenger1 and passenger2 to the collection. He must remove passenger1 and passenger2 from the collection. This is done in the car class with the operations "add passenger" and "remove passenger".

An add operation to attach an associated object in a 1:M adds an associated object to the collection of associated objects.

void addPassenger (Passenger &aPassenger)

{ aPassengerList.add (&aPassenger); }

The add operation may receive a pointer to the associated object or a reference to the associated object. The benefit of a reference is that any changes to the associated object in the attach operation will be reflected in the object itself.

The remove operation to detach an associated object removes an associated object from the collection of associated objects.

void removePassenger (Passenger &aPassenger)

{ aPassengerList.detach (&aPassenger);}

Figure Car class diagram showing 1 to many association.

Listing C++ code listing showing 1 to many association.

C++ Minimum Class Declaration with 1 : M Association - Header Files

//////////////////////////Car.h file////////////////////////////////////

#ifndef __CAR_H

#define __CAR_H

#ifndef __PASSENGR_H

#include "Passengr.h"

#endif

const int maxNumberOfPassengers = 4;

class Car

{ int speed; //Attribute data member

int currentPassengersIndex; //Index for array of 1:M association objects

//1:M association object data member

//Change C array to C++ collection class with iterator

Passenger* currentPassengers [maxNumberOfPassengers ];

// Null association object for initialization of association object data member

Passenger nullPassenger;

public:

Car () : speed(0)

{ currentPassengersIndex = 0; //Index for array of 1:M association objects

//Initialization of array of 1:M association objects to null association objects

for ( int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

//Alternative initialization currentPassengers[i] =0

}

void addPassenger (Passenger& aPassenger) ;

void removePassenger (Passenger& aPassenger) ;

~ Car ( ) { } //Destructor

};

#endif

//////////////////////////Passengr.h file////////////////////////////////////

#ifndef __PASSENGR_H

#define __PASSENGR_H

class Passenger

{ int seatBeltStatus; //Attribute data member

public:

Passenger () : seatBeltStatus(0) { }

void checkPassengerSeatBelt () ;

~ Passenger ( ) { } //Destructor

};

#endif

C++ Source Code Files

//////////////////////////Car.cpp file////////////////////////////////////

#include "Car.h"

void Car::addPassenger(Passenger& aPassenger) {

}

void Car::removePassenger(Passenger& aPassenger) {

}

//////////////////////////Passengr.cpp file////////////////////////////////////

#include "Passengr.h"

void Passenger::checkPassengerSeatBelt() {

}

C++ Main Function

//////////////////////////main.cpp file////////////////////////////////////

#include "Car.h"

int main ()

{

Car car1; //invokes the default constructor

Passenger passenger1;

car1.addPassenger (passenger1);

car1.removePassenger (passenger1);

return 0;

}

  1. Minimum C++ Code Generation Scripts for 1 : M Association

To generate the C++ class declaration and function definitions, we used two scripts. A class declaration script generated the Car.h file and a function definition script generated the Car.cpp file. We created the main.cpp manually. The two scripts are shown below.

Script to Generate C++ Minimum Class Declaration with 1 : M Association - Header File

//////////////////////////TRUNCATE_EIGHT$CLASS_NAME.h file////////////////////////////////////

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H

#define __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H

[

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$ASSOCIATION_MANY_CLASS$_H

#include "TRUNCATE_EIGHT$ASSOCIATION_MANY_CLASS$.h"

#endif

]

NO_OUTPUT_BEGIN Use the the CLASS_USER fields for typedef, enum, const declarations, e.g.

const int maxNumberOfTires = 4; NO_OUTPUT_END

CLASS_USER1

CLASS_USER2

class CLASS_NAME[NO_RETURN NO_REPEAT: NO_REPEAT public BASE_CLASS ,DELETE_LAST_SYMBOL]

{ [CPP_ATTRIBUTE_STATIC CPP_ATTRIBUTE_CONSTANT ATTRIBUTE_TYPE ATTRIBUTE_NAME$; //Attribute data member]

[int ASSOCIATION_MANY_NAME$Index; //Index for array of 1:M association objects]

[ //1:M association object data member

//Change C array to C++ collection class with iterator

ASSOCIATION_MANY_CLASS$* ASSOCIATION_MANY_NAME LITERAL_SYMBOL[maxNumberOf$ASSOCIATION_MANY_CLASS$s LITERAL_SYMBOL];]

[ // Null association object for initialization of association object data member

ASSOCIATION_MANY_CLASS$ null$ASSOCIATION_MANY_CLASS;]

public:

CLASS_NAME ()

SELECT_WHEN LOGICAL_NOT ATTRIBUTE_IS_STATIC [NO_RETURN NO_REPEAT: ATTRIBUTE_NAME(ATTRIBUTE_INITIAL_VALUE),DELETE_LAST_SYMBOL]

{ [ASSOCIATION_MANY_NAME$Index = 0; //Index for array of 1:M association objects ]

[ //Initialization of array of 1:M association objects to null association objects

for ( int i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS; ]

}

[ CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME (CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL;

]

OPERATION_CPP_VIRTUAL_BASE_CLASS ~ CLASS_NAME ( ) { } //Destructor

};

#endif

Script to Generate C++ Function Definitions - .cpp File

//////////////////////////TRUNCATE_EIGHT$CLASS_NAME.cpp file////////////////////////////////////

#include "TRUNCATE_EIGHT$CLASS_NAME.h"

[

OPERATION_RETURN_TYPE CLASS_NAME::OPERATION_NAME(CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT

{

OPERATION_CODE

}

]

  1. Enhanced C++ Coding for 1 to Many Association

To code C++ classes with 1 to many association, create a class declaration and function definitions as shown in the diagrams below. Key aspects of the class declaration are shown on the left. This information class diagram shows that a class declaration of the first class (class with association) should have an include statement for the association class file, a class name, data members, a traversal data member collection holding pointers to objects of the association class, a constructor, traversal function members to access an object of the association class, traversal data member accessor functions, function members, and a destructor. This information class diagram shows that the first class (class with association) is connected to the second class (association class) with the traversal data member collection. The traversal data member collection is used to access the object of the second class (association class). The class diagram on the right shows sample C++ identifiers that are also in the code listings.

Figure Class diagram showing 1 to Many association

Key aspects of coding a class with association are listed below. The class may or may not create and delete association objects:

- Declare a #include compiler directive to include the association class, e.g. #include "Passengr.h". If required include the collection class that holds association objects.

- Declare an association object data member - array or collection object to hold pointers to association objects, e.g. Passenger *currentPassengers [maxNumberOfPassengers];

- Define a default constructor to initialize an object with default data member values. Since the array holds pointers, initialize each pointer to 0. Car (){for (int i = 0; i < maxNumberOfPassengers; i++) currentPassengers[i] = 0;

- Define a constructor with arguments to initialize an object with passed values. Optionally pass a pointer to an array or collection object and assign the array or collection object. Car (int aSpeed, Passenger* pPassengers) { currentPassengers [0] = *pPassengers; }

- Define a copy constructor to initialize an object with a copy of another object. Optionally assign the array or collection object to the array or collection object of the copy. Optional iterator. Following code only if you desire to copy 1:M association objects Car (const Car& aCar) {for (i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i] = aCar.currentPassengers [i]; }

- Define an assignment operator (operator=) to assign one object to another. Optionally assign the array or collection object. Optional iterator. Following code only if you desire to assign 1:M association objects Car& operator= (const Car& aCar) ) {for (i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i] = aCar.currentPassengers [i]; }

- Define an equality operator (operator==) to compare two objects. Optionally compare the array or collection object. Optional iterator for a member by member comparison. int operator== (const Car& aCar);

- Define input function - C++ insertion operator for use with cin. Must invoke the array or collection object operator>>. Iterator required. friend istream& operator>> (istream& is, Car& aCar) {for (i = 0, i < maxNumberOfPassengers; i++) is >> *aCar.currentPassengers [0]; }

- Define the output function - C++ extraction operator for use with cout. Must invoke the association object operator<<. Iterator required. friend ostream& operator<< (ostream& os, Car& aCar) { for (i = 0, i < maxNumberOfPassengers; i++) os << *aCar.currentPassengers [0]; }

- Define a get and set function for the collection of association objects, e.g. Passenger* getCurrentPassenger () {return currentPassengers[0]; }

- Define get, set, remove, removeAll, exists, and exists (a specific object) assessor functions for individual association objects, e.g. Passenger* getPassenger () {return currentPassengers[0];

- Define a default destructor to deinitialize an object, ~Car () {}

- Define a main (test) function to create an association object with several association objects and invoke a traversal function

To code the second class, optionally, declare an inverse traversal data member, e.g. Car * aCar; Prior to compiling the association class, insert a forward declaration before the association class declaration, e.g. class Car; The complete C++ code listing is below.

Listing C++ Code Listing for 1 to Many Association

C++ Class Declaration with 1 : M Association - Header File

// Class: Car //ANSI C++

#ifndef __CAR_H //Required for Car class

#define __CAR_H

#ifndef __IOSTREAM_H //Required for cin and cout

#include <iostream.h>

#endif

#ifndef __CSTRING_H //Required for CString class

#include <CString.h>

#endif

//Required for 1:M association classes

#ifndef __PASSENGR_H //Passenger

#include "Passengr.h"

#endif

const int maxNumberOfPassengers = 4;

class Car

{

int speed; //Attribute data member

int currentPassengersIndex; //Index for array of 1:M association objects

//1:M association object data member

//Change C array to C++ collection class with iterator

Passenger* currentPassengers [maxNumberOfPassengers ];

// Null association object for initialization of association object data member

Passenger nullPassenger;

public:

//Default constructor alternative to compiler provided default constructor

//Ensure correct initial values

//Initialization list has members in the order declared

//Association object data member pointers initialized to null association object

Car ();

//Constructor with arguments

//Update to argument list to initialize base class data members,

//e.g. (int aNumber) : BaseClass (aNumber)

Car ( int aspeed ) ;

//Copy Constructor

Car (const Car& aCar );

//Operator= Assignment Operator

Car& operator= (const Car& aCar);

//Operator== Equality Operator

int operator== (const Car& aCar) const;

//Operator<< for cout

friend ostream& operator<< (ostream& os, const Car& aCar);

//Operator>> for cin

friend istream& operator>> (istream& is, Car& aCar);

//Get accessor function for non-static attribute data member

int getspeed() const

{ return speed;

}

//Set accessor function for non-static attribute data member

void setspeed (const int aspeed)

{ speed = aspeed;

}

//Get accessor function for 1:M association collection

const Passenger* getPassengerCollection() const ;

//Set accessor function for 1:M association collection

void setPassengerCollection (Passenger* const aPassengerCollection);

//Add function for 1:M association object data member

void addPassenger (Passenger* const aPassenger); //throw (string)

//Remove function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void removeLastPassenger ( ) ;//throw (string)

//Remove all function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void removeAllPassengers ( ) ;//throw (string)

//Get accessor function for 1:M association object data member

const Passenger* getFirstPassenger() const ;//throw (string)

//Exists function for 1:M association object data member

int existsPassenger() const ;

//Exists function for 1:M association object data member

int existsPassenger (Passenger* const aPassenger) const ;

// void addPassenger (Passenger& aPassenger) ;

void removePassenger (Passenger& aPassenger) ;

~ Car ( ) { } //Destructor - Delete any pointer data members that used new in constructors

//Destructor should be virtual if and only if class contains at least one virtual function

//Objects destroyed in the reverse order of the construction order

};

#endif

C++ Source Code File

//////////////////////////.cpp file/////////////////////////////////////////////////////

#include "Car.h"

void Car::removePassenger(Passenger& aPassenger)

{

}

//Default constructor alternative to compiler provided default constructor

//Association object data member pointers initialized to null association object

Car::Car ()

: speed(0)

{ currentPassengersIndex = 0; //Index for array of 1:M association objects

//Initialization of array of 1:M association objects to null association objects

for ( int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

}

//Constructor with arguments

Car::Car ( int aspeed )

{ speed = aspeed; //Initialization of attributes

currentPassengersIndex = 0; //Index for array of 1:M association objects

//Initialization of array of 1:M association objects to null association objects

for ( int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

}

//Copy constructor alternative to compiler provided default copy constructor

Car::Car (const Car& aCar )

{int i = 0;

currentPassengersIndex = 0; //Index for array of 1:M association objects

speed = aCar.speed;

for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

//Initialization of pointers to null association object

//Commented out shallow copy

//for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = aCar.currentPassengers [i ] ;

}

//Operator= Assignment Operator alternative to compiler provided operator=

Car& Car::operator= (const Car& aCar)

{ if (this == &aCar) return *this;

int i = 0;

speed = aCar.speed;

for (i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger ; //Initialization of pointers to null association object

//for (i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = aCar.currentPassengers [i ] ;

return *this;

}

//Operator== Equality Operator

int Car::operator== (const Car& aCar) const

{ return (

//Equality check for 1:M association objects for shallow compare

//Update for the correct number of associated objects

( currentPassengers [0 ] == aCar.currentPassengers [0 ])&&

( currentPassengers [1 ] == aCar.currentPassengers [1 ])&&

( currentPassengers [2 ] == aCar.currentPassengers [2 ])&&

( currentPassengers [3 ] == aCar.currentPassengers [3 ])&&

//Equality check for attribute data members

(speed == aCar.speed)

);

}

//Operator<< extraction for cout

ostream& operator<< (ostream& os, const Car& aCar)

{ int i = 0;

os << "Object Attribute Values - Class Car" << endl;

os << "speed: " << aCar.speed << endl;

for (i = 0; i < maxNumberOfPassengers; i++)

{ if ( aCar.currentPassengers [i ] != &aCar.nullPassenger) os << " currentPassengers: " << *aCar.currentPassengers [i ] << endl;

}

return os;

}

//Operator>> insertion for cin

istream& operator>> (istream& is, Car& aCar)

{ int i = 0;

cout << "\nEnter Object Attribute Values or 0 - Class Car";

cout << "\nEnter speed : " << endl;

is >> aCar.speed;

for (i = 0; i < maxNumberOfPassengers; i++)

{ if ( aCar.currentPassengers [i ]!= &aCar.nullPassenger) is >> *aCar.currentPassengers [i ] ;

}

return is;

}

//Get accessor function for 1:M association object data member

const Passenger* Car::getFirstPassenger() const //throw (string)

{ string PassengerCollectionEmpty;

if ( currentPassengersIndex == 0 ) throw PassengerCollectionEmpty;

else return currentPassengers [currentPassengersIndex ];

}

//Get accessor function for 1:M association collection

const Passenger* Car::getPassengerCollection() const

{ return *currentPassengers;

}

//Set accessor function for 1:M association collection

void Car::setPassengerCollection (Passenger* const aPassengerCollection)

{ int i = 0;

for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [ i ] = &nullPassenger ;

for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [ i ] = &aPassengerCollection [ i ];

}

//Add function for 1:M association object data member

void Car::addPassenger (Passenger* const aPassenger) //throw (string)

{ string PassengerCollectionFull;

if ( currentPassengersIndex == maxNumberOfPassengers) throw PassengerCollectionFull;

else

{ currentPassengers [ currentPassengersIndex ] = aPassenger ;

currentPassengersIndex++;

}

}

//Remove function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void Car::removeLastPassenger ( ) //throw (string)

{ string PassengerCollectionEmpty;

if ( currentPassengersIndex == 0 ) throw PassengerCollectionEmpty;

else

{ currentPassengersIndex--;

currentPassengers [currentPassengersIndex ] = &nullPassenger ;

}

}

//Remove all function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void Car::removeAllPassengers ( ) //throw (string)

{ string PassengerCollectionEmpty;

if ( currentPassengersIndex == 0 ) throw PassengerCollectionEmpty;

for (int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

}

//Exists function for 1:M association object data member

int Car::existsPassenger() const

{ if ( currentPassengers [0 ] == &nullPassenger ) return 0; else return 1;

}

//Exists function for 1:M association object data member

int Car::existsPassenger (Passenger* const aPassenger) const

{ if ( currentPassengers [ 0 ] == &nullPassenger ) return 0;

for (int i = 0; i < maxNumberOfPassengers; i++)

{ if ( currentPassengers [i ] == aPassenger ) return 1;

}

return 0;

}

  1. Modeling Association for Quality Software

How we model association can affect the quality of the software in terms of correctness, reliability, extendibility, and reusability. For example, if we have excessive association connections, then extendibility may be limited. It may be difficult to make changes to the software without causing excessive adverse side-effects.

In modeling association we can utilize for the software quality techniques of weak coupling and strong cohesion. Coupling is the degree of interconnectivity between entities. Association connects classes and connects objects. Association is required to accomplish the purpose of the system. However, we should strive for a reasonable amount of association to logically connect classes to accomplish the purpose of the system. We should avoid an excessive amount of association in which all classes seem to be associated with each other. A class diagram with excessive association appears as a "spaghetti bowl" of association connections everywhere. We should strive for a moderate degree of association for weak coupling. With weak coupling we can make a change in one class without unexpected adverse side-effects in another class. The general guideline is to identify sufficient associations in a system for an understandable class structure to accomplish the purpose of the system.

Strong cohesion is the degree of internal relatedness of elements within a larger, more complex entity. We can get strong cohesion by ensuring attributes and operations related to the association support the purpose of the class. We can check to ensure that there are no out-of-place attributes, operations, and associations. Having sufficient (not excessive) associations can favorably affect cohesion. We should remove any associations that seem illogical or out-of-place.

  1. Summary

In O-O modeling it is important to identify and describe relationships between classes and between objects. A relationship is a link or connection between classes or between objects. The association relationship is the "has a" relationship. The aggregation relationship is the "part of" relationship. Aggregation is a special form of association with special semantics (rules) for deletion and propagation of operations. The generalization specialization relationship is the "is a" relationship between superclasses and subclasses. Relationships are shown on the class diagram. Relationships may be specified in a relationship specification. Using a CASE tool, a class diagram showing relationships between classes may be created. The CASE tool may generate source code to implement the classes and the relationships.

free cialis submit=free cialis cialis com cialis order java.js buy cheap cialis online cialis exchange link cialis tadalafil american express viagra cialis buy cialis link mycialsnowprohostingcom onlinehtml cialis impotence drug eli lilly co cialis without prescription in detroit area why cialis buy cialis link onlinehtm pharmacyrxfreewebtoolscom cialis in south africa do u take cialis everyday add cialis url cialis and manufacturer cialis muncie indiana how to stop viagra cialis spam black buy casino cialis diet followup gambling jack low online order phentermine poker post viagra cialis comparison levitra cialis online sales mexican cialis boelolokeepkidshealthycom cialis link cialis day next cialis purchase mixing cialis with effexor bulk cialis and viagra sold world wide on line cialis discount save cialis story safest of cialis levitra viagra buy cialis href newopasblogdrivecom cialis en venezuela cialis western open tee times viagra and cialis cheap buy cialis link onlinecolnu cialis europe viagra cialis submit=cialis should i buy cialis online buy cialis amsterdam cialis dose cialis tablet sildenafil cialis generico buy cialis cialisfunsurforg onlinehtml cialis drug impotence cialis testimonials sitemap1 buy cialis no prescription cialis for order cialis side effects order cialis buy cialis dreampharmaceuticals cialis drug cialis peak serum time half life pill cutters for cialis blindness cialis cialis dysfunction erectile cialis pill low cost generic cialis blogid buy casino cialis inurl order phentermine poker viagra cialis compare viagra cialis soft tabs den haag results of comparisons of viagra and cialis buy cialis in uk cialis en espanol cialis prescriptions map buy cheap cialis cialis link onlineinfo cialis cost low cialis online sale mixing viagra and cialis black buy casino cialis diet followup gambling jack order phentermine poker viagra cialis cheapest online prices cialis news information about cialis and livetra black buy casino cialis diet gambling jack online order phentermine poker tag viagra xhtml cialis class action suit cialis open ticket western order cialis online black buy casino cialis diet holdem jack online order phentermine poker tag texas viagra xhtml cialis comment info personal remember cialis order in south africa is cialis over the counter drug black casino cialis diet followup gambling health jack phentermine poker viagra cialis company cialis on line generic soft tab cialis better erections by combining cialis and viagra cialis attorney ohio cialis melt tabs how does cialis work black buy casino cheap cialis diet followup gambling health jack online order phentermine poker viagra cialis black box warnings cialis mexico online how to get best results with cialis archive buy cialis cialis discount generic cialis online purchase how viagra cialis levitra work black buy casino cialis diet followup gambling jack online order phentermine poker viagra cialis cedar park cialis mg index best cialis generic price cialis and no prescription required cialis link pharmacyrawcsorg generic cialis online best place to get totally free viagra or cialis samples cialis and venous leak