Lesson 5 | A derived class and the "IS-A relationship" |
Objective | Several pairs of example classes fit definition |
IS-A relationship in Object Oriented Programming
Determine whether several pairs of example classes fit the definition of class and subclass. In our student/graduate student example, grad_student is the derived class and student is the base class. The use of the keyword public following the colon in the derived class header means that the protected and public members of student are to be inherited as protected and
public members of grad_student. Members that are private are inaccessible. This is referred to as public inheritance.
Public inheritance also means that the derived class grad_student is a subtype or subclass of student.
Thus, a graduate student is a student, but a student does not have to be a graduate student. This subtyping relationship is called the ISA relationship. This is also called interface inheritance. A derived class is a modification of the base class that inherits the public and protected members of the base class. The only members that cannot be inherited are constructors and any member function that overloads the assignment operator. Let us look at an example of public inheritance using the student and grad_student classes.
`Base` and `Derived` classes using:
✅ Updated C++ best practices (as of 2025), including:
- Modern class naming conventions (
PascalCase
)
enum class
instead of unscoped enums
- Use of
std::string
instead of char*
and fixed-size C-style arrays
- Constructor initialization lists
- Virtual function for polymorphic behavior (
print()
)
This code is written to compile and run on MS Visual Studio 2019 or higher with a C++17 or later standard (including C++23).
✅ Rewritten Code
#include <iostream>
#include <string>
enum class AcademicYear { Freshman, Sophomore, Junior, Senior, Graduate };
class Student {
public:
Student(const std::string& name, int id, double gpa, AcademicYear year)
: studentId(id), gpa(gpa), year(year), name(name) {}
virtual void print() const {
std::cout << "Name: " << name << "\n"
<< "ID: " << studentId << "\n"
<< "GPA: " << gpa << "\n"
<< "Year: " << static_cast<int>(year) << "\n";
}
protected:
int studentId;
double gpa;
AcademicYear year;
std::string name;
};
enum class SupportType { TA, RA, Fellowship, Other };
class GradStudent : public Student {
public:
GradStudent(const std::string& name, int id, double gpa, AcademicYear year,
SupportType support, const std::string& dept, const std::string& thesis)
: Student(name, id, gpa, year), support(support), department(dept), thesis(thesis) {}
void print() const override {
Student::print();
std::cout << "Support: " << static_cast<int>(support) << "\n"
<< "Department: " << department << "\n"
<< "Thesis: " << thesis << "\n";
}
protected:
SupportType support;
std::string department;
std::string thesis;
};
✅ Example Usage in `main()`
int main() {
GradStudent gs("Alice Johnson", 202301, 3.92, AcademicYear::Graduate,
SupportType::RA, "Physics", "Quantum Entanglement Simulation");
gs.print();
return 0;
}
🔍 Improvements Made Based on 2025 C++ Practices
Feature |
Legacy Code |
Modernized Code (2025) |
Class Naming |
student , grad_student |
Student , GradStudent |
Enum Usage |
enum year , enum support |
enum class AcademicYear , SupportType |
String Handling |
char name[30] |
std::string name |
Function Overriding |
Just redefined |
Used virtual + override |
Constructor Style |
Only declarations |
Used initialization lists |
Encapsulation/Access |
protected for all |
Kept protected for inheritance |
Output Format |
None |
std::cout in print() |
- Protected Members
The student members student_id, gpa, name, y, and print() are inherited by grad_student. In the class student, these members are protected. This makes them visible to the derived class, grad_student, but otherwise treated as private.
Notice that the student constructor is not inherited, even though it is a public member of the base class.
Distinguish between "is-a" relationship and "has-a" relationship
The is-a relationship represents inheritance. In an is-a relationship, an object of a derived class also can be treated as an object of its base class. For example, a car is a vehicle, so any attributes and behaviors of a vehicle are also attributes and behaviors of a car.
By contrast, the "has-a relationship" represents composition. The folloing link discussses
Aggregation. In a "has-a relationship", an object contains one or more objects of other classes as members. For example, a car includes many components. A car has a
- steering wheel,
- brake pedal, and
- transmission.
Derived-class member functions
Derived-class member functions might require access to base-class data members and member functions. A derived class can access the non-private members of its base class. Base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.
-
Derived-class member functions might require access to base-class data members and member functions.
- Derived classes often extend or modify behavior defined in a base class. For this reason, they frequently need access to the base class's members—especially protected or public ones—to reuse or enhance the functionality.
-
A derived class can access the non-private members of its base class.
- In C++, the accessibility of base class members in a derived class depends on the access specifier used:
- Public and protected members of the base class are accessible in the derived class.
- Private members are not accessible directly in the derived class.
-
Base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.
- This is standard object-oriented practice. Declaring a member as private ensures encapsulation and restricts access only to the base class itself—not even derived classes can access it directly.
Summary:
Base Class Access Specifier |
Accessible in Derived Class? |
public |
✅ Yes |
protected |
✅ Yes |
private |
❌ No |
These principles are foundational in C++ inheritance and encapsulation.
A
derived class[1] can change the values of private base-class members, but only through non-private member functions provided in the base class and inherited into the derived class.
Public Inheritance - Quiz
Classes Subtypes Exercise
When you have completed the quiz, return here and click the Exercise link to determine whether several pairs of example classes fit the definition of class and subclass.
Classes Subtypes - Exercise
[1]derived class: A derived class is a class created or derived from another existing class.
