Inheritance, Polymorphism, Virtual Functions, and Abstract Classes
Understand object-oriented extension in C++ using inheritance, overriding, runtime polymorphism, and abstract interfaces.
Inside this chapter
- Inheritance Basics
- Virtual Functions and Dynamic Dispatch
- Abstract Classes
- Composition Versus Inheritance
- Destructor Warning
- Real-World Usage Snapshot
Series navigation
Study the chapters in order for the clearest path from C++ basics to modern ownership, templates, concurrency, performance, and production-ready engineering practices. Use the navigation at the bottom to move smoothly through the full series.
Inheritance Basics
class Animal {
public:
virtual void speak() const {
std::cout << "Animal sound\n";
}
virtual ~Animal() = default;
};
class Dog : public Animal {
public:
void speak() const override {
std::cout << "Woof\n";
}
};
Inheritance models an is-a relationship. It is useful when subtype behavior genuinely extends a base abstraction, but overusing inheritance can create rigid designs.
Virtual Functions and Dynamic Dispatch
Virtual functions enable runtime polymorphism, meaning the correct overridden method is chosen based on the actual object type, even through a base pointer or reference.
Abstract Classes
class Shape {
public:
virtual double area() const = 0;
virtual ~Shape() = default;
};
Pure virtual functions make a class abstract. This is useful for defining interfaces that different concrete classes must implement.
Composition Versus Inheritance
One of the most important design lessons in C++ is that composition is often safer and more flexible than inheritance. Inheritance is powerful, but it should be used intentionally, not automatically.
Destructor Warning
Base classes intended for polymorphic use should typically have virtual destructors. Otherwise deleting a derived object through a base pointer can cause incomplete cleanup and undefined behavior.
Real-World Usage Snapshot
Polymorphism appears in graphics systems, plugin architectures, device abstraction, parser hierarchies, GUI frameworks, and many extensible libraries. Strong C++ developers know when runtime polymorphism is the right tool and when simpler alternatives are better.