C++: Inheritance Basics
Last updated: 2026-08-26
Imagine you wrote
StudentandTeacherclasses, and found they both have name and age, but students have student IDs and teachers have employee IDs.Can you reuse the
Personclass code? Inheritance does exactly that — creating a "parent-child" relationship between classes.
1. What Is Inheritance?
(1) 1.1 Inheritance in Everyday Life
| Real-Life Example | Program Equivalent |
|---|---|
| A child inherits traits from parents (eye color, height, etc.) | A derived class inherits members from its base class |
| A child can have their own traits (like special talents) | A derived class can add new members |
The essence of inheritance: Creating new classes by extending existing ones.
(2) 1.2 Why Do We Need Inheritance?
Without inheritance (duplicate code):
▶ Example 2: Code Example (Difficulty ⭐)
#include <iostream>
#include <string>
// Student class
class Student {
std::string name;
int age;
std::string studentId;
};
// Teacher class
class Teacher {
std::string name; // ❌ Duplicated
int age; // ❌ Duplicated
std::string teacherId;
};
Output:
(program output)
With inheritance (code reuse):
#include <iostream>
#include <string>
// Base class (parent class)
class Person {
public:
std::string name;
int age;
};
// Derived class (child class)
class Student : public Person {
public:
std::string studentId; // New member
};
class Teacher : public Person {
public:
std::string teacherId; // New member
};
2. Basic Syntax of Inheritance
(1) 2.1 Declaring a Derived Class
Syntax:
class DerivedClassName : inheritanceMode BaseClassName {
// new members
};
Example:
#include <iostream>
#include <string>
class Person {
public:
std::string name;
int age;
};
// Student inherits Person
class Student : public Person {
public:
std::string studentId;
};
int main() {
Student s1;
s1.name = "Alice"; // ✅ Inherited name
s1.age = 20; // ✅ Inherited age
s1.studentId = "2024001"; // Own member
std::cout << "Name: " << s1.name << std::endl;
std::cout << "Age: " << s1.age << std::endl;
std::cout << "Student ID: " << s1.studentId << std::endl;
return 0;
}
3. Inheritance Modes (Access Control)
(1) 3.1 Three Inheritance Modes
| Base Class Member \ Inheritance Mode | public Inheritance | protected Inheritance | private Inheritance |
|---|---|---|---|
| public members | public (unchanged) | protected | private |
| protected members | protected | protected | private |
| private members | Not accessible | Not accessible | Not accessible |
💡 Key Point: The most commonly used inheritance mode is public inheritance.
(2) 3.2 public Inheritance (Recommended)
#include <iostream>
#include <string>
class Person {
private:
std::string id; // Private member: not accessible by derived class
protected:
std::string address; // Protected member: accessible by derived class
public:
std::string name; // Public member: accessible by everyone
void introduce() {
std::cout << "My name is " << name << std::endl;
}
};
class Student : public Person {
public:
void setAddress(const std::string& addr) {
address = addr; // ✅ Can access protected member
// id = "123"; // ❌ Cannot access private member
}
};
int main() {
Student s1;
s1.name = "Alice"; // ✅ Accessible
// s1.address = "Wuhan"; // ❌ Not accessible (protected)
return 0;
}
4. Constructors and Inheritance
(1) 4.1 Derived Class Constructor Call Order
Rule: The base class constructor is called first, then the derived class constructor.
#include <iostream>
#include <string>
class Person {
public:
Person() {
std::cout << "Person constructor" << std::endl;
}
};
class Student : public Person {
public:
Student() {
std::cout << "Student constructor" << std::endl;
}
};
int main() {
Student s1;
return 0;
}
💡 Key Point: The destructor call order is reversed — the derived class destructor is called first, then the base class destructor.
5. Practice: Simple Student Management System (Inheritance Version)
▶ Example 1: Implementation Using Inheritance (Difficulty ⭐⭐)
#include <iostream>
#include <string>
// Base class
class Person {
protected:
std::string name;
int age;
public:
Person(const std::string& n, int a) : name(n), age(a) {}
void introduce() {
std::cout << "Name: " << name << ",Age: " << age << std::endl;
}
};
// Derived class: Student
class Student : public Person {
private:
std::string studentId;
double score;
public:
Student(const std::string& n, int a, const std::string& id, double s)
: Person(n, a), studentId(id), score(s) {}
void introduce() {
Person::introduce(); // Call base class introduce
std::cout << "Student ID: " << studentId << ",Score: " << score << std::endl;
}
};
int main() {
Student s1("Alice", 20, "2024001", 92.5);
s1.introduce();
return 0;
}
Output:
Name: Alice,Age: 20
Student ID: 2024001,Score: 92.5
❓ FAQ
public inheritance: most commonly used, preserves the base class's interface > - protected inheritance: rarely used > - private inheritance: rarely used▶ Example 3: Derived Class Constructor (Difficulty ⭐)
#include <iostream>
#include <string>
class Animal {
protected:
std::string name;
public:
Animal(std::string n) : name(n) {}
void speak() { std::cout << name << "makes a sound" << std::endl; }
};
class Dog : public Animal {
public:
Dog(std::string n) : Animal(n) {}
void speak() { std::cout << name << "barks" << std::endl; }
};
int main() {
Dog dog("Wangcai");
dog.speak();
return 0;
}
Output:
Wangcaibarks
📖 Summary
- Inheritance lets derived classes reuse base class code
- public inheritance is the most commonly used
- Derived classes cannot access
privatemembers of the base class - Derived classes can access
protectedmembers of the base class - Constructor call order: base class → derived class
📝 Exercises
-
Basic (Difficulty ⭐): Define an
Animalbase class with anamemember. HaveDogandCatclasses inherit from it. -
Intermediate (Difficulty ⭐⭐): Extend the above program by adding a
void speak()virtual function toAnimal(you'll learn about virtual functions later), and haveDogandCatoverride it. -
Challenge (Difficulty ⭐⭐⭐): Design a library management system class hierarchy:
-
Person(name, age) -
StudentinheritsPerson(student ID, number of books borrowed) -
TeacherinheritsPerson(employee ID, number of books borrowed) -
Implement borrow and return functionality.
-
Inheritance: derived classes have all members of the base class
- public/protected/private inheritance controls access permissions
- Derived class constructors call base class constructors
- is-a relationship: a derived class is a kind of base class
- Diamond inheritance requires virtual inheritance to resolve ambiguity
6. 🚀 Next Steps
Now that you've learned inheritance basics, let's move on to Polymorphism (Lesson 32) — allowing base class pointers to call derived class functions for "one interface, multiple implementations"!