Skills101

C++ Programming · Lesson 4 of 9 · Updated ·

Inheritance and Virtual Functions in C++ — Polymorphism, Abstract Classes

Inheritance lets a class reuse another; virtual functions let one piece of code work with many related types (runtime polymorphism).

1. Basic inheritance

#include <iostream>
#include <string>
using namespace std;

class Employee {
protected:                 // visible to subclasses, not to outside code
    string name;
    double salary;
public:
    Employee(string n, double s) : name(n), salary(s) {}
    string describe() const { return name + " earns " + to_string((int)salary); }
};

class Manager : public Employee {
    int teamSize;
public:
    Manager(string n, double s, int t) : Employee(n, s), teamSize(t) {}   // call the base constructor
    string team() const { return name + " leads " + to_string(teamSize); }
};

int main() {
    Manager m("Neha", 90000, 6);
    cout << m.describe() << " | " << m.team() << "\n";
    return 0;
}
Neha earns 90000 | Neha leads 6

Access modes

With class B : public A (the usual), A's public members stay public in B. protected / private inheritance makes them protected / private in B — rarely needed.

Construction order

Base constructor first, then derived; destructors in reverse order (derived first).

2. Virtual functions

A Shape pointer calling s->area() runs Circle::area() or Square::area() depending on the real object, thanks to virtual functions and the vtable

#include <iostream>
#include <vector>
#include <memory>
using namespace std;

class Shape {
public:
    virtual double area() const = 0;        // pure virtual → Shape is abstract
    virtual ~Shape() = default;             // virtual destructor (important!)
};

class Circle : public Shape {
    double r;
public:
    explicit Circle(double r) : r(r) {}
    double area() const override { return 3.14159 * r * r; }
};

class Square : public Shape {
    double a;
public:
    explicit Square(double a) : a(a) {}
    double area() const override { return a * a; }
};

int main() {
    vector<unique_ptr<Shape>> shapes;
    shapes.push_back(make_unique<Circle>(1));
    shapes.push_back(make_unique<Square>(3));
    double total = 0;
    for (const auto &s : shapes) total += s->area();   // the right area() runs
    cout << total << "\n";
    return 0;
}
12.1416
  • virtual: the call is decided by the actual object at runtime (through a hidden table of function pointers, the vtable).
  • override: asks the compiler to check that you really override a virtual function (catches typos).
  • = 0 makes a function pure virtual; a class with one is abstract and can't be instantiated.

What happens without virtual?

#include <iostream>
using namespace std;

struct Animal { void speak() const { cout << "..."; } };
struct Dog : Animal { void speak() const { cout << "Woof"; } };

int main() {
    Dog d;
    Animal &a = d;
    a.speak();          // not virtual → Animal::speak runs
    cout << " ";
    d.speak();
    cout << "\n";
    return 0;
}
... Woof

3. Why destructors must be virtual

If you delete a derived object through a base pointer and the base destructor is not virtual, only the base part is destroyed — a resource leak (formally undefined behaviour). Rule: a class with any virtual function should have a virtual destructor.

4. Multiple inheritance (briefly)

C++ allows class C : public A, public B. The diamond problem (A and B share a base) is solved with virtual inheritance (class A : virtual public Base). Use multiple inheritance sparingly — mostly for "interfaces" (classes with only pure virtual functions).

Common mistakes

  • Forgetting virtual in the base class → the wrong function runs.
  • Missing virtual destructor in a polymorphic base class.
  • Object slicing: assigning a Dog to an Animal by value cuts off the Dog part; use references or pointers.

Quick recap

  • class Derived : public Base; call the base constructor in the initializer list.
  • virtual + override = runtime polymorphism via the vtable.
  • Pure virtual (= 0) → abstract class.
  • Polymorphic base classes need virtual destructors; avoid slicing.

Practice what you learned

📝 Quiz: Inheritance and Virtual Functions5 questions · instant answers & explanations · +10 XP · counts towards your free certificateTake the quiz →