Inheritance and virtual functions in C++
Base and derived classes, virtual functions and override, abstract classes, and why virtual destructors matter.
A derived class inherits from a base class and can override its virtual functions. Calling a virtual function through a base pointer or reference runs the version for the object's real type: that's runtime polymorphism.
- Write
overrideon overrides so the compiler catches signature mistakes. - A pure virtual function (
= 0) makes the class abstract: an interface that can't be instantiated. - Give a polymorphic base class a
virtualdestructor, or deleting through a base pointer is undefined behavior. - Pass polymorphic objects by reference or pointer; passing by value slices off the derived part.
Example
#include <iostream>
#include <memory>
#include <vector>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() = default;
};
struct Rect : Shape {
double w, h;
Rect(double w_, double h_) : w(w_), h(h_) {}
double area() const override { return w * h; }
};
struct Circle : Shape {
double r;
explicit Circle(double r_) : r(r_) {}
double area() const override { return 3.14 * r * r; }
};
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Rect>(2, 3));
shapes.push_back(std::make_unique<Circle>(1));
double total = 0;
for (const auto &s : shapes) total += s->area();
std::cout << total << "\n";
return 0;
}
Output:
9.14
Watch it run: Virtual functions pick the real type