[ fromfile: inheritance-intro.xml id: derivation1 ]
The pound sign (#
) that precedes Student::m_Year
indicates that m_Year
is a protected
member of that class.
Recall that protected
members of a class are accessible to the member functions of derived classes.
The other data members of Student
are private
and, hence, inaccessible to the member functions of the derived classes.
The open triangle arrowhead (pointing to the base class) indicates class inheritance.
That arrow is also called generalization because it points from the more specific (derived) class to the more general (base) class.
The derived classes are also called subclasses of the base class.
Example 6.1 shows the definitions of the three classes.
Example 6.1. src/derivation/qmono/student.h
#ifndef STUDENT_H #define STUDENT_H #include <QString> class Student { public: Student(QString nm, long id, QString major, int year = 1); ~Student() {} QString getClassName() const; QString toString() const; private: QString m_Name; QString m_Major; long m_StudentId; protected: int m_Year; QString yearStr() const; }; class Undergrad: public Student { public: Undergrad(QString name, long id, QString major, int year, int sat); QString getClassName() const; QString toString() const; private: int m_SAT; }; class GradStudent : public Student { public: enum Support { ta, ra, fellowship, other }; GradStudent(QString nm, long id, QString major, int yr, Support support); QString getClassName() const ; QString toString() const; protected: static QString supportStr(Support sup) ; private: Support m_Support; }; #endif // #ifndef STUDENT_H
The classHead of each derived class specifies the base class from which it is derived and the kind of derivation used.
Example 6.2 defines the member functions of Student
.
Example 6.2. src/derivation/qmono/student.cpp
[ . . . . ] #include <QTextStream> #include "student.h" Student::Student(QString nm, long id, QString major, int year) : m_Name(nm), m_Major(major), m_StudentId(id), m_Year(year) {} QString Student::getClassName() const { return "Student"; } QString Student::toString() const { QString retval; QTextStream os(&retval); os << "[" << getClassName() << "]" << " name: " << m_Name << "; Id: " << m_StudentId << "; Year: " << yearStr() << "; \nMajor: " << m_Major ; return retval; }
The Undergrad
member functions are defined in Example 6.3.
Example 6.3. src/derivation/qmono/student.cpp
[ . . . . ] Undergrad::Undergrad(QString name, long id, QString major, int year, int sat) : Student(name, id, major, year), m_SAT(sat) { } QString Undergrad::getClassName() const { return "Undergrad"; } QString Undergrad::toString() const { QString result; QTextStream os(&result); os << Student::toString() << " [SAT: " << m_SAT << " ]\n"; return result; }
Because each Undergrad
is a
Student
, whenever you create an Undergrad
object, you must also create and initialize a Student
.
Furthermore, you must call a Student
constructor to initialize the Student
part of any derived object.
In the member initializers of a constructor, you can treat the base class name as an implicit member of the derived class.
It gets initialized first, before the initialization of the derived class members.
If you do not specify how the base class is initialized, its default constructor is called.
If there is no base class default constructor, the compiler reports an error.
GradStudent
has some added features that you need to handle properly, as shown in Example 6.4.
Example 6.4. src/derivation/qmono/student.cpp
[ . . . . ] GradStudent:: GradStudent(QString nm, long id, QString major, int yr, Support support) :Student(nm, id, major, yr), m_Support(support) { } QString GradStudent::toString() const { return QString("%1%2%3 ]\n") .arg(Student::toString()) .arg(" [Support: ") .arg(supportStr(m_Support)); }
Another QString style. | |
Call the base class version | |
Then add items that are specific to GradStudent. |
Extending.
Inside both derived class versions of toString()
, before the derived class attributes are handled, we explicitly call Student::toString()
, which handles the (private
) base class attributes. Each derived class version of toString()
extends the functionality of Student::toString()
.
A derived class object cannot directly access the private members of Student
even though it contains those members.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |