C++ · OOP: inheritance and virtual functions
Public inheritance, virtual functions and runtime polymorphism, override, pure virtual (abstract) classes, and virtual destructors.
In Python every method call is resolved at runtime. In C++ you have to ask for that with virtual:
- A
virtualmethod called through a base pointer or reference runs the derived class’s version. Withoutvirtual, the base version runs. - Mark overrides with
overrideso the compiler catches signature typos. = 0makes a method pure virtual, and the class becomes abstract (you can’t create one directly).- A base class used through pointers needs a
virtualdestructor (Core Guideline C.35). Otherwise deleting through a base pointer skips the derived destructor.
#include <iostream>
#include <memory>
#include <vector>
struct Shape {
virtual ~Shape() = default;
virtual double area() const = 0; // pure virtual
virtual const char* name() const { return "shape"; }
const char* plainName() const { return "shape (non-virtual)"; }
};
struct Circle : Shape {
double r;
explicit Circle(double r) : r(r) {}
double area() const override { return 3.14159 * r * r; }
const char* name() const override { return "circle"; }
};
struct Rect : Shape {
double w, h;
Rect(double w, double h) : w(w), h(h) {}
double area() const override { return w * h; }
const char* name() const override { return "rect"; }
};
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(1.0));
shapes.push_back(std::make_unique<Rect>(2.0, 3.0));
for (const auto& s : shapes)
std::cout << s->name() << " / " << s->plainName() << " -> " << s->area() << '\n';
}
Output:
circle / shape (non-virtual) -> 3.14159
rect / shape (non-virtual) -> 6Sources
- Virtual function specifier — cppreference.com
- Abstract class — cppreference.com
- C++ Core Guidelines C.35: base class destructor — Standard C++ Foundation