The Student Class Design

At this point, the design plan for the Student class is to use a string object to represent the name and a valarray<double> object to represent the quiz scores. How should this be done? You might be tempted to publicly derive a Student class from these two classes. That would be an example of multiple public inheritance, which C++ allows, but it would be inappropriate here. The reason is that the relationship of a student to these classes doesn’t fit the is-a model. A student is not a name. A student is not an array of quiz scores. What you have here is a has-a relationship. A student has a name, and a student has an array of quiz scores. The usual C++ technique for modeling has-a relationships is to use composition or containment—that is, to create a class composed of, or containing, members that are objects of another class. For example, you can begin a Student class declaration like this:

class Student
{
private:
    string name;              // use a string object for name
    valarray<double> scores;  // use a valarray<double> object for scores
    ...
};

As usual, the class makes the data members private. This implies that the Student class member functions can use the public interfaces of the string and valarray<double> classes to access and modify the name and scores objects, but the outside world cannot do so. The only access the outside world will have to name and scores is through the public interface defined for the Student class (see Figure 14.1). A common way of describing this is to say that the Student class acquires the implementation of its member objects but doesn’t inherit the interface. For example, a Student object uses the string implementation rather than a char * name or a char name[26] implementation for holding the name. But a Student object does not innately have the ability to use the string operator+=() function for appending.

Figure 14.1. Objects within objects: containment.

Image

The fact that a class object doesn’t automatically acquire the interface of a contained object is a good thing for a has-a relationship. For example, string overloads the + operator to allow concatenating two strings, but, conceptually, it doesn’t make sense to concatenate two Student objects. That’s one reason not to use public inheritance in this case. On the other hand, parts of the interface for the contained class may make sense for the new class. For example, you might want to use the operator<() method from the string interface to sort Student objects by name. You can do so by defining a Student::operator<() member function that internally uses the string::operator<() function. Let’s move on to some details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.35.193