cpp
examples
examples.cpp⚙️cpp
/**
* Inheritance in C++ - Comprehensive Examples
*
* Demonstrates:
* - Basic inheritance
* - Access specifiers
* - Constructor/destructor order
* - Function overriding
* - Multiple inheritance
*
* Compile: g++ -std=c++17 -Wall -Wextra examples.cpp -o examples
* Run: ./examples
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// ============================================================
// SECTION 1: BASIC INHERITANCE
// ============================================================
class Animal {
protected:
string name;
int age;
public:
Animal(const string& n, int a) : name(n), age(a) {
cout << " Animal constructor: " << name << endl;
}
~Animal() {
cout << " Animal destructor: " << name << endl;
}
void eat() const {
cout << " " << name << " is eating" << endl;
}
void sleep() const {
cout << " " << name << " is sleeping" << endl;
}
string getName() const { return name; }
int getAge() const { return age; }
};
class Dog : public Animal {
private:
string breed;
public:
Dog(const string& n, int a, const string& b)
: Animal(n, a), breed(b) {
cout << " Dog constructor: " << name << endl;
}
~Dog() {
cout << " Dog destructor: " << name << endl;
}
void bark() const {
cout << " " << name << " says: Woof!" << endl;
}
void displayInfo() const {
cout << " " << name << " is a " << age << " year old " << breed << endl;
}
string getBreed() const { return breed; }
};
void demonstrateBasicInheritance() {
cout << "--- Basic Inheritance ---\n" << endl;
cout << "Creating a Dog (derived from Animal):" << endl;
Dog dog("Buddy", 3, "Labrador");
cout << "\nUsing inherited methods:" << endl;
dog.eat(); // Inherited from Animal
dog.sleep(); // Inherited from Animal
cout << "\nUsing Dog-specific methods:" << endl;
dog.bark();
dog.displayInfo();
cout << "\nLeaving scope:" << endl;
}
// ============================================================
// SECTION 2: ACCESS SPECIFIERS IN INHERITANCE
// ============================================================
class Base {
public:
int publicVar = 1;
void publicMethod() { cout << " Base::publicMethod" << endl; }
protected:
int protectedVar = 2;
void protectedMethod() { cout << " Base::protectedMethod" << endl; }
private:
int privateVar = 3;
void privateMethod() { cout << " Base::privateMethod" << endl; }
};
class PublicDerived : public Base {
public:
void accessMembers() {
publicVar = 10; // OK: public
protectedVar = 20; // OK: protected accessible in derived
// privateVar = 30; // ERROR: private not accessible
publicMethod(); // OK
protectedMethod(); // OK
// privateMethod(); // ERROR
}
void showAccess() {
cout << " PublicDerived accessing Base members:" << endl;
cout << " publicVar: " << publicVar << endl;
cout << " protectedVar: " << protectedVar << endl;
}
};
void demonstrateAccessSpecifiers() {
cout << "\n--- Access Specifiers in Inheritance ---\n" << endl;
PublicDerived pd;
// From outside the class
cout << "Accessing from outside:" << endl;
cout << " publicVar: " << pd.publicVar << endl; // OK: still public
// cout << pd.protectedVar; // ERROR: protected
pd.publicMethod(); // OK
// pd.protectedMethod(); // ERROR
cout << "\nAccessing from inside derived class:" << endl;
pd.showAccess();
}
// ============================================================
// SECTION 3: CONSTRUCTOR AND DESTRUCTOR ORDER
// ============================================================
class Grandparent {
public:
Grandparent() { cout << " 1. Grandparent constructor" << endl; }
~Grandparent() { cout << " 4. Grandparent destructor" << endl; }
};
class Parent : public Grandparent {
public:
Parent() { cout << " 2. Parent constructor" << endl; }
~Parent() { cout << " 3. Parent destructor" << endl; }
};
class Child : public Parent {
public:
Child() { cout << " 3. Child constructor" << endl; }
~Child() { cout << " 2. Child destructor" << endl; }
};
void demonstrateConstructorOrder() {
cout << "\n--- Constructor/Destructor Order ---\n" << endl;
cout << "Creating Child object:" << endl;
{
Child c;
cout << "\nChild object in use..." << endl;
cout << "\nLeaving scope:" << endl;
}
cout << "After scope" << endl;
}
// With parameters
class Person {
protected:
string name;
public:
Person(const string& n) : name(n) {
cout << " Person(" << name << ")" << endl;
}
virtual ~Person() {
cout << " ~Person(" << name << ")" << endl;
}
};
class Employee : public Person {
protected:
int employeeId;
public:
Employee(const string& n, int id) : Person(n), employeeId(id) {
cout << " Employee(" << name << ", " << employeeId << ")" << endl;
}
~Employee() override {
cout << " ~Employee(" << name << ")" << endl;
}
};
class Manager : public Employee {
private:
string department;
public:
Manager(const string& n, int id, const string& dept)
: Employee(n, id), department(dept) {
cout << " Manager(" << name << ", " << department << ")" << endl;
}
~Manager() override {
cout << " ~Manager(" << name << ")" << endl;
}
};
void demonstrateParameterizedConstructors() {
cout << "\n--- Parameterized Constructors ---\n" << endl;
cout << "Creating Manager:" << endl;
{
Manager m("Alice", 1001, "Engineering");
cout << "\nUsing manager..." << endl;
cout << "\nDestroying:" << endl;
}
}
// ============================================================
// SECTION 4: FUNCTION OVERRIDING
// ============================================================
class Shape {
public:
virtual void draw() const {
cout << " Drawing generic shape" << endl;
}
virtual double area() const {
return 0;
}
void describe() const { // Non-virtual
cout << " I am a shape with area: " << area() << endl;
}
virtual ~Shape() = default;
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() const override {
cout << " Drawing rectangle " << width << "x" << height << endl;
}
double area() const override {
return width * height;
}
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() const override {
cout << " Drawing circle with radius " << radius << endl;
}
double area() const override {
return 3.14159 * radius * radius;
}
};
void demonstrateFunctionOverriding() {
cout << "\n--- Function Overriding ---\n" << endl;
Rectangle rect(5, 3);
Circle circle(4);
cout << "Direct calls:" << endl;
rect.draw();
rect.describe();
cout << endl;
circle.draw();
circle.describe();
cout << "\nPolymorphic calls through base pointer:" << endl;
Shape* shapes[] = { &rect, &circle };
for (Shape* s : shapes) {
s->draw(); // Calls appropriate override
cout << " Area: " << s->area() << endl;
}
}
// ============================================================
// SECTION 5: CALLING BASE CLASS METHODS
// ============================================================
class Logger {
public:
virtual void log(const string& message) {
cout << "[LOG] " << message << endl;
}
};
class TimestampLogger : public Logger {
public:
void log(const string& message) override {
cout << "[2024-01-01 12:00:00] ";
Logger::log(message); // Call base version
}
};
class PrefixLogger : public Logger {
private:
string prefix;
public:
PrefixLogger(const string& p) : prefix(p) {}
void log(const string& message) override {
Logger::log(prefix + ": " + message);
}
};
void demonstrateCallingBase() {
cout << "\n--- Calling Base Class Methods ---\n" << endl;
Logger basic;
TimestampLogger timestamp;
PrefixLogger prefixed("ERROR");
basic.log("Basic message");
timestamp.log("Timestamp message");
prefixed.log("Something went wrong");
}
// ============================================================
// SECTION 6: MULTIPLE INHERITANCE
// ============================================================
class Printable {
public:
virtual void print() const = 0;
virtual ~Printable() = default;
};
class Serializable {
public:
virtual string serialize() const = 0;
virtual ~Serializable() = default;
};
class Document : public Printable, public Serializable {
private:
string title;
string content;
public:
Document(const string& t, const string& c) : title(t), content(c) {}
void print() const override {
cout << " === " << title << " ===" << endl;
cout << " " << content << endl;
}
string serialize() const override {
return "{\"title\":\"" + title + "\",\"content\":\"" + content + "\"}";
}
};
void demonstrateMultipleInheritance() {
cout << "\n--- Multiple Inheritance ---\n" << endl;
Document doc("My Document", "This is the content.");
cout << "Using Printable interface:" << endl;
doc.print();
cout << "\nUsing Serializable interface:" << endl;
cout << " " << doc.serialize() << endl;
// Can use through either interface
Printable* printable = &doc;
Serializable* serializable = &doc;
cout << "\nThrough Printable pointer:" << endl;
printable->print();
}
// ============================================================
// SECTION 7: DIAMOND PROBLEM AND VIRTUAL INHERITANCE
// ============================================================
// Without virtual inheritance (problematic)
class AnimalBase {
public:
int id = 0;
AnimalBase() { cout << " AnimalBase()" << endl; }
};
class MammalNonVirtual : public AnimalBase {
public:
MammalNonVirtual() { cout << " MammalNonVirtual()" << endl; }
};
class BirdNonVirtual : public AnimalBase {
public:
BirdNonVirtual() { cout << " BirdNonVirtual()" << endl; }
};
// This would have TWO copies of AnimalBase::id
// class BatNonVirtual : public MammalNonVirtual, public BirdNonVirtual { };
// With virtual inheritance (solution)
class MammalVirtual : virtual public AnimalBase {
public:
MammalVirtual() { cout << " MammalVirtual()" << endl; }
};
class BirdVirtual : virtual public AnimalBase {
public:
BirdVirtual() { cout << " BirdVirtual()" << endl; }
};
class Bat : public MammalVirtual, public BirdVirtual {
public:
Bat() { cout << " Bat()" << endl; }
};
void demonstrateDiamondProblem() {
cout << "\n--- Diamond Problem & Virtual Inheritance ---\n" << endl;
cout << "Creating Bat with virtual inheritance:" << endl;
Bat bat;
cout << "\nBat has single id: " << bat.id << endl;
bat.id = 42;
cout << "After setting: " << bat.id << endl;
// With non-virtual: bat.MammalNonVirtual::id vs bat.BirdNonVirtual::id
// With virtual: just bat.id (one copy)
}
// ============================================================
// SECTION 8: ABSTRACT BASE CLASSES
// ============================================================
class AbstractShape {
public:
virtual double area() const = 0; // Pure virtual
virtual double perimeter() const = 0; // Pure virtual
virtual void draw() const { // Virtual with default
cout << " Drawing shape..." << endl;
}
void info() const { // Non-virtual
cout << " Area: " << area() << ", Perimeter: " << perimeter() << endl;
}
virtual ~AbstractShape() = default;
};
class Square : public AbstractShape {
private:
double side;
public:
Square(double s) : side(s) {}
double area() const override {
return side * side;
}
double perimeter() const override {
return 4 * side;
}
void draw() const override {
cout << " Drawing square with side " << side << endl;
}
};
class Triangle : public AbstractShape {
private:
double a, b, c;
public:
Triangle(double a, double b, double c) : a(a), b(b), c(c) {}
double area() const override {
double s = (a + b + c) / 2;
return sqrt(s * (s-a) * (s-b) * (s-c));
}
double perimeter() const override {
return a + b + c;
}
};
void demonstrateAbstractClasses() {
cout << "\n--- Abstract Base Classes ---\n" << endl;
// AbstractShape shape; // ERROR: cannot instantiate abstract class
Square square(5);
Triangle triangle(3, 4, 5);
cout << "Square:" << endl;
square.draw();
square.info();
cout << "\nTriangle:" << endl;
triangle.draw(); // Uses inherited default
triangle.info();
// Polymorphism with abstract base
vector<AbstractShape*> shapes = { &square, &triangle };
cout << "\nPolymorphic processing:" << endl;
for (const auto* shape : shapes) {
shape->info();
}
}
// ============================================================
// SECTION 9: INHERITANCE AND COMPOSITION
// ============================================================
// Composition: HAS-A relationship
class Engine {
private:
int horsepower;
public:
Engine(int hp) : horsepower(hp) {}
void start() { cout << " Engine started (" << horsepower << "hp)" << endl; }
void stop() { cout << " Engine stopped" << endl; }
};
class Wheel {
public:
void rotate() { cout << " Wheel rotating" << endl; }
};
// Car HAS-A Engine and HAS-A Wheels
class CarComposition {
private:
Engine engine;
Wheel wheels[4];
public:
CarComposition(int hp) : engine(hp) {}
void start() {
engine.start();
}
void drive() {
for (auto& wheel : wheels) {
wheel.rotate();
}
}
};
// Inheritance: IS-A relationship
class Vehicle {
public:
virtual void move() = 0;
virtual ~Vehicle() = default;
};
class CarInheritance : public Vehicle {
public:
void move() override {
cout << " Car is driving" << endl;
}
};
void demonstrateCompositionVsInheritance() {
cout << "\n--- Composition vs Inheritance ---\n" << endl;
cout << "Composition (Car HAS-A Engine, Wheels):" << endl;
CarComposition car(200);
car.start();
car.drive();
cout << "\nInheritance (Car IS-A Vehicle):" << endl;
CarInheritance vehicle;
vehicle.move();
}
// ============================================================
// MAIN FUNCTION
// ============================================================
int main() {
cout << "╔════════════════════════════════════════════════════════════════════╗" << endl;
cout << "║ C++ INHERITANCE - EXAMPLES ║" << endl;
cout << "║ Creating Class Hierarchies ║" << endl;
cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 1: Basic Inheritance ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateBasicInheritance();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 2: Access Specifiers ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateAccessSpecifiers();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 3: Constructor Order ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateConstructorOrder();
demonstrateParameterizedConstructors();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 4: Function Overriding ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateFunctionOverriding();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 5: Calling Base Methods ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateCallingBase();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 6: Multiple Inheritance ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateMultipleInheritance();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 7: Diamond Problem ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateDiamondProblem();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 8: Abstract Base Classes ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateAbstractClasses();
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 9: Composition vs Inheritance ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
demonstrateCompositionVsInheritance();
cout << "\n╔════════════════════════════════════════════════════════════════════╗" << endl;
cout << "║ Examples Complete! ║" << endl;
cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
return 0;
}