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

Source: https://skills101.in/learn/cpp/cpp-inheritance-and-virtual-functions — Skills101 free tutorial (C++ Programming). Updated 2026-11-09.

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

## 1. Basic inheritance

```cpp
#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;
}
```

```text
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](https://skills101.in/learn-img/cpp/virtual-dispatch.svg)

```cpp
#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;
}
```

```text
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?

```cpp
#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;
}
```

```text
... 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 quiz and free certificate: https://skills101.in/learn/cpp/cpp-inheritance-and-virtual-functions