Download presentation
Presentation is loading. Please wait.
1
Class Relationships in C++
CS 123/CS 231
2
Class Diagram Notation Revisited
Multiplicity Association and Navigability Composition Aggregation
3
Mandatory Relationships
class Car { private: Engine engine; … } Car Engine 1 engine class Department { private: Employee *head; … Department(); // no default public: Department(Employee& h) { head = &h; } … } Department Employee 1 head
4
Optional Relationship
class Book { private: Patron *borrower; … public: Book() { borrower = NULL; } void setBorrower(Patron& p) { borrower = &p; void returnBook() { borrower = NULL; … Patron Book 0..1 borrower
5
Multiple and Mandatory
Car Wheel 4 wheels // Option 1: Array of objects // use for composition relationships class Car { private: Wheel wheels[4]; ... } // Option 2: Array of pointers class Car { private: Wheel *wheels[4]; // wheel objects may be created externally ... Car(); public: Car(Wheel& w1, Wheel& w2, … ) … // wheel references required in constructor }
6
Multiple but not Mandatory
class Patron { private: Book *borrowed[3]; int numBooks; // counter … public: Patron() { numBooks = 0; } void borrow(Book& b) { if (numBooks < 3) borrowed[numBooks++] = &b; Patron Book 0..3 borrowed
7
“One-to-Many” Relationships
Collection required but size is not fixed Dynamically allocate the array Use a pointer and new to create the array Use 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 structure e.g., a list structure that maintains a collection of pointers (or objects)
8
“One-to-Many” Examples
Invoice Order Line * lines Teacher Student 1 * advisor advisees Catalog Book * booklist
9
Using a Variable-sized Array
class 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() Book * booklist
10
Implementing Collections through a Data Structure
Note: Although it is not incorrect to include the LinkedList class (and other details) in a class diagram, it is often not necessary because it is more of an implementation detail on how a collection is carried out. class Catalog { private: LinkedList booklist; … public: void addBook(Book& b) { booklist.insert(b); } Catalog * Book versus Catalog 1 Linked List Node 1 Book 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 both Note: we provided both directions for the Patron-Book example, but we did not have to Decision 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 sufficient Example: Employee and Spouse For 1-to-Many relationships, allow navigation at least from the “Many” participant Example: 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 * * Enrollment Student Enrollment
grade Student Enrollment grade Course * * What about navigability?
14
Navigability and Association Classes
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?) … } class Enrollment { private: Student *student; Course *course; double grade; … }
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 objects To facilitate searching for objects in an association based on a search key For example, in the collection class for Enrollment, we could have maps that use student-id and/or course-number as keys Carrying out the operation “list all courses and grades that student 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 parts Hide 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
class Car { private: Engine *engine; Car(); public: Car(Engine& e); … } Car Engine 1 engine Problem: Programmer can still perform engine = NULL; within this 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 &-reference as a member, engine has to refer to an actual Engine object
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.