1 / 19

Class Relationships in C++

Class Relationships in C++. CS 123/CS 231. Class Diagram Notation Revisited. Multiplicity Association and Navigability Composition Aggregation. Mandatory Relationships. class Car { private: Engine engine; … }. Car. Engine. 1. engine. class Department { private:

jkiernan
Download Presentation

Class Relationships in C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Class Relationships in C++ CS 123/CS 231

  2. Class Diagram NotationRevisited • 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 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 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 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, enginehas to refer to an actual Engine object

More Related