1 class relationships in c++ cs 123/cs 231. 2 class diagram notation revisited zmultiplicity...
TRANSCRIPT
1
Class Relationships in C++
CS 123/CS 231
2
Class Diagram NotationRevisited
MultiplicityAssociation and NavigabilityCompositionAggregation
3
Mandatory Relationships
Car1
engineEngine
class Car{private: Engine engine; …}
Department1
headEmployee
class Department{private: Employee *head; … Department(); // no defaultpublic: Department(Employee& h) { head = &h; } …}
4
Optional Relationship
Patron0..1
borrowerBook
class Book{private: Patron *borrower; …public: Book() { borrower = NULL; } void setBorrower(Patron& p) { borrower = &p; } void returnBook() { borrower = NULL; … } …}
5
Multiple and Mandatory
Car4
wheelsWheel
// Option 2: Array of pointersclass Car {private: Wheel *wheels[4]; // wheel objects may be created externally ... Car();public: Car(Wheel& w1, Wheel& w2, … ) … // wheel references required in constructor}
// Option 1: Array of objects// use for composition relationshipsclass Car {private: Wheel wheels[4]; ...}
6
Multiple but not Mandatory
Patron0..3
borrowedBook
class Patron{private: Book *borrowed[3]; int numBooks; // counter …public: Patron() { numBooks = 0; } void borrow(Book& b) { if (numBooks < 3) borrowed[numBooks++] = &b; … } …}
7
“One-to-Many” Relationships
Collection required but size is not fixedDynamically allocate the array
Use a pointer and new to create the arrayUse pointer-to-pointers-to-objects if you want
to handle references; use pointer-to-objects if you want to create the objects within the class (composition).
Or, use a container data structuree.g., a list structure that maintains a collection
of pointers (or objects)
8
“One-to-Many” Examples
Invoice*
lines
OrderLine
Catalog*
booklistBook
Teacher*
adviseesStudent
1
advisor
9
Using a Variable-sized Arrayclass Catalog{private: Book *booklist; int capacity; int listSize; …public: Catalog(int startSize) { booklist = new Book[startSize]; // note that Book objects are created here capacity = startSize; listSize = 0; } void addBook(Book& b) { if (listSize < capacity) booklist[listSize++] = b; // question: what happens here? else // resize array and then add } …}
Catalog
addBook()
*
booklistBook
10
Implementing Collections through a Data Structure
class Catalog{private: LinkedList booklist; …public: void addBook(Book& b) { booklist.insert(b); } …}
Note: Although it is not incorrectto include the LinkedList class (and otherdetails) in a class diagram, it is often notnecessary because it is more of animplementation detail on how a collectionis carried out.
Catalog * Book
Catalog1 Linked
ListBookNode
versus
1
next
11
Associations and Navigability
Given two classes A and B that are associated
Navigability is the ability to access associated objects from a given class
Can provide a way to get to the B objects from A, to the A objects from B, or bothNote: we provided both directions for the Patron-
Book example, but we did not have toDecision often depends on the use cases
Or, create an association class
12
Common Implementations for Associations
For 1-to-1 relationships, one-way navigability is often sufficientExample: Employee and Spouse
For 1-to-Many relationships, allow navigation at least from the “Many” participantExample: Faculty-Advisor and Student
For Many-to-Many relationships, provide two directions, or create an association class
*Note that there are efficiency and update considerations/tradeoffs
13
Association Class
Student Course
Student Course
* *
Enrollmentgrade
Enrollmentgrade **
What about navigability?
14
Navigability and Association Classes
class Enrollment{private: Student *student; Course *course; double grade;…}
class Student{private: … Enrollment **list; // collection of enrollment records // for the student (may be useful)…}
class Course{private: … Enrollment **list; // collection of enrollment records // for the course (useful?)…}
15
Navigability and Associative Maps
In collection classes for associations, it is also helpful to use maps (key-object pairs) instead of a list of just the objectsTo facilitate searching for objects in an
association based on a search keyFor example, in the collection class for
Enrollment, we could have maps that use student-id and/or course-number as keysCarrying out the operation “list all courses and
grades that student 222-11-0000 has taken” is now possible without the list member in student
16
Composition
Recall that the essence of composition is that the part is created and destroyed with the whole
It is thus “natural” (at least in C++) to use object members to implement a composition relationship
But it is possible to use pointers to part-objects and let the constructors and the destructor take care of the consistent creation and destruction of the parts
17
Aggregation
Standing recommendation: use pointers to represent the parts and ensure that object construction of the whole requires the user to specify the partsHide the default constructor and have a user-
defined constructor whose parameters are references to the parts
Parts can be created externally, but need to be included when creating the whole
Problem: It is still possible (within the class) to have a whole without the part
18
Problem with Mandatory Parts and Object Pointers
Car1
engineEngine
class Car{private: Engine *engine; Car();public: Car(Engine& e); …} Problem: Programmer can still
perform engine = NULL; withinthis class
19
Option: Using Members as &-References (aliases)
class Car{private: Engine &engine; Car();public: Car(Engine& e): engine(e) { … } … // can update engine here // but it can’t be “nullified”}
Solution: By using a &-referenceas a member, engine has to referto an actual Engine object