In C++, inheritance is one of the important features of object-oriented programming. It allows a class (called a subclass or derived class) to “inherit” members (member variables and member functions) from another class (called the base class or parent class), thereby reusing existing code and extending functionality. Imagine if we have an “Animal” class with general behaviors like “eating” and “sleeping”; then specific animal classes like “Dog” and “Cat” can directly inherit from the “Animal” class without repeating these general codes.
I. How to Define Parent and Child Classes¶
First, we need to define a parent class and then a child class that inherits from it. Taking “Animal” and “Dog” as examples:
// Parent class: Animal (动物)
class Animal {
public:
string name; // Animal's name (public member, accessible directly by subclasses)
int age; // Animal's age (public member, accessible directly by subclasses)
// Method to eat (public member function, callable directly by subclasses)
void eat() {
cout << name << " is eating." << endl;
}
// Method to sleep (public member function, callable directly by subclasses)
void sleep() {
cout << name << " is sleeping." << endl;
}
private:
int weight; // Weight (private member, not directly accessible by subclasses)
public:
// Public interface to set weight (indirect access to private member)
void setWeight(int w) {
weight = w;
}
int getWeight() {
return weight;
}
};
// Child class: Dog (狗), inherits from Animal
class Dog : public Animal { // public inheritance: Parent class members retain their original access rights in the subclass
public:
// Dog-specific method (new member in subclass)
void bark() {
cout << name << " is barking!" << endl;
}
};
II. How a Subclass Inherits Parent Class Member Variables¶
Parent class member variables are categorized into three access levels: public, protected, and private. Their access rules in the subclass differ:
- public member variables: Directly accessible by the subclass.
For example, theDogclass inheritsnameandagefromAnimal, sonameandagecan be directly used inDog.
Dog myDog;
myDog.name = "Buddy"; // Directly access parent class's public member
myDog.age = 3; // Directly access parent class's public member
-
private member variables: Not directly accessible by the subclass, but can be indirectly manipulated via public interfaces provided by the parent class (e.g.,
setWeight/getWeight).
For example,Animal’sweightis private. The subclassDogcannot directly writemyDog.weight, but can callmyDog.setWeight(15)to set the weight. -
protected member variables: Only directly accessible by the subclass and its subclasses (beginners can learn about this briefly).
III. How a Subclass Inherits Parent Class Member Functions¶
Similar to member variables, parent class member functions have different access rules based on their permissions:
-
public member functions: Directly callable by the subclass.
For example,Animal’seat()andsleep()are public, so the subclassDogcan directly callmyDog.eat()ormyDog.sleep(). -
private member functions: Not directly callable by the subclass; must be indirectly called via the parent class’s public interface (same logic as private variables).
-
protected member functions: Only directly callable by the subclass (beginners can learn about this briefly).
int main() {
Dog myDog;
myDog.name = "Buddy";
myDog.age = 3;
myDog.eat(); // Call parent class's public member function (outputs "Buddy is eating.")
myDog.bark(); // Call subclass's new member function (outputs "Buddy is barking!")
myDog.sleep(); // Call parent class's public member function (outputs "Buddy is sleeping.")
myDog.setWeight(15); // Set private member via parent class interface
cout << "Weight: " << myDog.getWeight() << endl; // Outputs 15
return 0;
}
IV. Impact of Different Inheritance Methods¶
C++ has three inheritance methods that affect the access rights of the parent class members in the subclass:
| Inheritance Method | Access Right of Parent’s public members in Subclass | Access Right of Parent’s protected members in Subclass | Access Right of Parent’s private members in Subclass |
|---|---|---|---|
| public | public | protected | Invisible (cannot be directly accessed) |
| private | private | private | Invisible |
| protected | protected | protected | Invisible |
Note for Beginners:
- The most commonly used is public inheritance (can be implicitly used if not specified, but explicit writing is recommended). In this case, the parent class’s public and protected members retain their original permissions, while private members are invisible.
- The other two methods (private/protected inheritance) are typically used for special scenarios (e.g., hiding parent class interfaces) and can be temporarily ignored by beginners.
V. Inheritance and Initialization of Constructors¶
The parent class constructor cannot be directly inherited, but the subclass constructor must first initialize the parent class part. For example, if Animal has a constructor:
class Animal {
public:
string name;
int age;
Animal(string n, int a) : name(n), age(a) { // Parent class constructor
cout << "Animal " << name << " created." << endl;
}
};
When constructing the subclass Dog, the initialization list must be used to call the parent class constructor:
class Dog : public Animal {
public:
// Subclass constructor: First call parent class constructor, then initialize self
Dog(string n, int a) : Animal(n, a) { // Must call parent class constructor first
cout << "Dog " << n << " created." << endl;
}
};
Key Point: When a subclass object is created, the parent class constructor is executed first, followed by the subclass constructor.
VI. Summary¶
The core of inheritance is code reuse and extension:
- Subclasses can directly inherit the parent class’s public/protected members (variables/functions) to avoid repetitive writing of general logic.
- The parent class’s private members must be accessed indirectly through public interfaces to ensure data encapsulation.
- Constructors must explicitly call the parent class constructor via the initialization list to complete initialization of the parent class part.
Through inheritance, more complex functions can be implemented with less code (e.g., the “Cat” and “Bird” classes can all inherit from “Animal” and add their own specific methods like Cat’s catchMouse()).
Practice Exercise: Try defining a Cat class that inherits from Animal and add a catchMouse() method. Then create a Cat object to test the inheritance effect.