cpp

examples

examples.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;
}
Examples - C++ Tutorial | DeepML