Inheritance allows a derived class (child) to acquire the properties and methods of a base class (parent). It promotes code reuse and establishes an "is-a" relationship.
Syntax: class Derived : accessSpecifier Base { ... };
| Inheritance Type | public members become | protected members become |
|---|---|---|
public | public in derived | protected in derived |
protected | protected in derived | protected in derived |
private | private in derived | private in derived |
#include <iostream>
#include <string>
using namespace std;
// Base class
class Animal {
protected:
string name;
int age;
public:
Animal(string name, int age) : name(name), age(age) {}
void eat() { cout << name << " is eating" << endl; }
void sleep() { cout << name << " is sleeping" << endl; }
void info() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
// Derived class - inherits from Animal
class Dog : public Animal {
private:
string breed;
public:
// Call base constructor via initializer list
Dog(string name, int age, string breed)
: Animal(name, age), breed(breed) {}
void bark() { cout << name << " says: Woof!" << endl; }
void info() { // override base info()
Animal::info(); // call base version
cout << "Breed: " << breed << endl;
}
};
int main() {
Dog d("Rex", 3, "German Shepherd");
d.eat(); // inherited from Animal
d.sleep(); // inherited from Animal
d.bark(); // Dog's own method
d.info(); // Dog's overridden info()
return 0;
}
#include <iostream>
using namespace std;
class Vehicle {
public:
void start() { cout << "Vehicle started" << endl; }
};
class Car : public Vehicle {
public:
void drive() { cout << "Car driving" << endl; }
};
// Multilevel: ElectricCar -> Car -> Vehicle
class ElectricCar : public Car {
public:
void charge() { cout << "Charging battery" << endl; }
};
int main() {
ElectricCar ec;
ec.start(); // from Vehicle
ec.drive(); // from Car
ec.charge(); // own method
return 0;
}
#include <iostream>
using namespace std;
class Flyable {
public:
void fly() { cout << "Flying" << endl; }
};
class Swimmable {
public:
void swim() { cout << "Swimming" << endl; }
};
// Multiple inheritance: Duck inherits from both
class Duck : public Flyable, public Swimmable {
public:
void quack() { cout << "Quack!" << endl; }
};
int main() {
Duck d;
d.fly(); // from Flyable
d.swim(); // from Swimmable
d.quack(); // own method
return 0;
}
In inheritance, constructors are called base first, derived last. Destructors are called in reverse order "” derived first, base last.
#include <iostream>
using namespace std;
class Base {
public:
Base() { cout << "Base constructor" << endl; }
~Base() { cout << "Base destructor" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived constructor" << endl; }
~Derived() { cout << "Derived destructor" << endl; }
};
int main() {
Derived d;
return 0;
}
/*
Output:
Base constructor <-- base first
Derived constructor
Derived destructor <-- derived first on destruction
Base destructor
*/
When you delete a derived object through a base class pointer, the base destructor is called "” not the derived one. This causes a memory leak if the derived class allocates resources. The fix: always declare the base class destructor as virtual.
#include <iostream>
using namespace std;
// WITHOUT virtual destructor "” memory leak!
class BadBase {
public:
~BadBase() { cout << "BadBase destructor" << endl; }
};
class BadDerived : public BadBase {
int *data;
public:
BadDerived() { data = new int[100]; }
~BadDerived() {
delete[] data; // NEVER called when deleted via BadBase*
cout << "BadDerived destructor" << endl;
}
};
// WITH virtual destructor "” correct!
class GoodBase {
public:
virtual ~GoodBase() { cout << "GoodBase destructor" << endl; }
};
class GoodDerived : public GoodBase {
int *data;
public:
GoodDerived() { data = new int[100]; }
~GoodDerived() override {
delete[] data; // called correctly
cout << "GoodDerived destructor" << endl;
}
};
int main() {
// Memory leak "” BadDerived destructor never called
BadBase *b = new BadDerived();
delete b; // only BadBase::~BadBase() runs!
cout << "---" << endl;
// Correct "” both destructors called
GoodBase *g = new GoodDerived();
delete g; // GoodDerived::~GoodDerived() then GoodBase::~GoodBase()
return 0;
}
// Rule: if a class has ANY virtual function, give it a virtual destructor.
The diamond problem occurs in multiple inheritance when two base classes share a common ancestor, causing the grandparent's members to be duplicated. virtual inheritance solves this by ensuring only one copy of the grandparent exists.
#include <iostream>
using namespace std;
// Animal
// / \
// Dog Cat
// \ /
// DogCat <-- diamond!
// WITHOUT virtual inheritance "” ambiguous, two copies of Animal
class Animal {
public:
void breathe() { cout << "Breathing" << endl; }
};
// Use 'virtual' to share a single Animal base
class Dog : virtual public Animal {
public:
void bark() { cout << "Woof!" << endl; }
};
class Cat : virtual public Animal {
public:
void meow() { cout << "Meow!" << endl; }
};
class DogCat : public Dog, public Cat {
public:
void speak() { bark(); meow(); }
};
int main() {
DogCat dc;
dc.breathe(); // unambiguous "” only ONE Animal base
dc.speak();
// Without 'virtual' above, dc.breathe() would be ambiguous:
// error: request for member 'breathe' is ambiguous
return 0;
}
Use final (C++11) to prevent a class from being inherited further, or to prevent a virtual function from being overridden in derived classes.
#include <iostream>
using namespace std;
class Base {
public:
virtual void greet() { cout << "Hello from Base" << endl; }
};
class Derived : public Base {
public:
// final on a method "” no further override allowed
void greet() override final {
cout << "Hello from Derived (final)" << endl;
}
};
// class MoreDerived : public Derived {
// void greet() override { } // ERROR: greet is final
// };
// final on a class "” cannot be inherited
class Sealed final : public Base {
public:
void greet() override { cout << "Sealed class" << endl; }
};
// class Child : public Sealed { }; // ERROR: Sealed is final
int main() {
Derived d;
d.greet(); // Hello from Derived (final)
Sealed s;
s.greet(); // Sealed class
return 0;
}
| Type | Description | Example |
|---|---|---|
| Single | One derived class inherits from one base class | Dog : Animal |
| Multilevel | Chain of inheritance: A → B → C | ElectricCar : Car : Vehicle |
| Multiple | One class inherits from two or more base classes | Duck : Flyable, Swimmable |
| Hierarchical | Multiple classes inherit from one base class | Dog, Cat, Bird : Animal |
| Hybrid | Combination of multiple inheritance types | Mix of above (use virtual inheritance) |
Explore 500+ free tutorials across 20+ languages and frameworks.