cpp

examples

examples.cpp⚙️
/**
 * Polymorphism in C++ - Examples
 * Compile: g++ -std=c++17 -Wall examples.cpp -o examples
 */

#include <iostream>
#include <string>
#include <vector>
#include <memory>

using namespace std;

// ============================================================
// SECTION 1: VIRTUAL FUNCTIONS BASICS
// ============================================================

class Animal {
public:
    virtual void speak() const {
        cout << "  Animal makes a sound" << endl;
    }
    virtual ~Animal() = default;
};

class Dog : public Animal {
public:
    void speak() const override {
        cout << "  Dog says: Woof!" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() const override {
        cout << "  Cat says: Meow!" << endl;
    }
};

void demoVirtualBasics() {
    cout << "--- Virtual Functions Basics ---\n" << endl;
    
    Dog dog;
    Cat cat;
    
    Animal* animals[] = { &dog, &cat };
    for (Animal* a : animals) {
        a->speak();  // Polymorphic call
    }
}

// ============================================================
// SECTION 2: VIRTUAL VS NON-VIRTUAL
// ============================================================

class Base {
public:
    void nonVirtual() const { cout << "  Base::nonVirtual" << endl; }
    virtual void isVirtual() const { cout << "  Base::isVirtual" << endl; }
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    void nonVirtual() const { cout << "  Derived::nonVirtual" << endl; }
    void isVirtual() const override { cout << "  Derived::isVirtual" << endl; }
};

void demoVirtualVsNonVirtual() {
    cout << "\n--- Virtual vs Non-Virtual ---\n" << endl;
    
    Derived d;
    Base* ptr = &d;
    
    cout << "Through Base pointer:" << endl;
    ptr->nonVirtual();  // Base version (static)
    ptr->isVirtual();   // Derived version (dynamic)
    
    cout << "\nDirect call:" << endl;
    d.nonVirtual();
    d.isVirtual();
}

// ============================================================
// SECTION 3: ABSTRACT CLASSES
// ============================================================

class Shape {
public:
    virtual double area() const = 0;
    virtual void draw() const = 0;
    virtual ~Shape() = default;
    
    void describe() const {
        cout << "  Area: " << area() << endl;
    }
};

class Rectangle : public Shape {
    double w, h;
public:
    Rectangle(double w, double h) : w(w), h(h) {}
    double area() const override { return w * h; }
    void draw() const override { cout << "  [Rectangle " << w << "x" << h << "]" << endl; }
};

class Circle : public Shape {
    double r;
public:
    Circle(double r) : r(r) {}
    double area() const override { return 3.14159 * r * r; }
    void draw() const override { cout << "  [Circle r=" << r << "]" << endl; }
};

void demoAbstractClasses() {
    cout << "\n--- Abstract Classes ---\n" << endl;
    
    vector<unique_ptr<Shape>> shapes;
    shapes.push_back(make_unique<Rectangle>(5, 3));
    shapes.push_back(make_unique<Circle>(4));
    
    for (const auto& s : shapes) {
        s->draw();
        s->describe();
    }
}

// ============================================================
// SECTION 4: VIRTUAL DESTRUCTOR
// ============================================================

class ResourceBase {
public:
    ResourceBase() { cout << "  ResourceBase()" << endl; }
    virtual ~ResourceBase() { cout << "  ~ResourceBase()" << endl; }
};

class ResourceDerived : public ResourceBase {
    int* data;
public:
    ResourceDerived() : data(new int[10]) { cout << "  ResourceDerived()" << endl; }
    ~ResourceDerived() override { delete[] data; cout << "  ~ResourceDerived()" << endl; }
};

void demoVirtualDestructor() {
    cout << "\n--- Virtual Destructor ---\n" << endl;
    
    cout << "With virtual destructor:" << endl;
    ResourceBase* ptr = new ResourceDerived();
    delete ptr;  // Both destructors called
}

// ============================================================
// SECTION 5: OVERRIDE AND FINAL
// ============================================================

class Vehicle {
public:
    virtual void start() { cout << "  Vehicle starting" << endl; }
    virtual void stop() { cout << "  Vehicle stopping" << endl; }
    virtual ~Vehicle() = default;
};

class Car : public Vehicle {
public:
    void start() override { cout << "  Car engine starting" << endl; }
    void stop() final { cout << "  Car braking" << endl; }  // Cannot override further
};

class SportsCar : public Car {
public:
    void start() override { cout << "  SportsCar roaring to life!" << endl; }
    // void stop() override {}  // ERROR: stop is final
};

void demoOverrideFinal() {
    cout << "\n--- Override and Final ---\n" << endl;
    
    SportsCar sc;
    Vehicle* v = &sc;
    v->start();
    v->stop();
}

// ============================================================
// SECTION 6: DYNAMIC CAST
// ============================================================

class Pet { public: virtual ~Pet() = default; };
class DogPet : public Pet { public: void fetch() { cout << "  Fetching!" << endl; } };
class CatPet : public Pet { public: void scratch() { cout << "  Scratching!" << endl; } };

void handlePet(Pet* p) {
    if (auto* dog = dynamic_cast<DogPet*>(p)) {
        dog->fetch();
    } else if (auto* cat = dynamic_cast<CatPet*>(p)) {
        cat->scratch();
    }
}

void demoDynamicCast() {
    cout << "\n--- Dynamic Cast ---\n" << endl;
    
    DogPet dog;
    CatPet cat;
    
    handlePet(&dog);
    handlePet(&cat);
}

// ============================================================
// SECTION 7: INTERFACE PATTERN
// ============================================================

class IDrawable {
public:
    virtual void draw() const = 0;
    virtual ~IDrawable() = default;
};

class IMoveable {
public:
    virtual void move(int x, int y) = 0;
    virtual ~IMoveable() = default;
};

class Sprite : public IDrawable, public IMoveable {
    int x = 0, y = 0;
    string name;
public:
    Sprite(const string& n) : name(n) {}
    void draw() const override { cout << "  Drawing " << name << " at (" << x << "," << y << ")" << endl; }
    void move(int dx, int dy) override { x += dx; y += dy; }
};

void demoInterfaces() {
    cout << "\n--- Interface Pattern ---\n" << endl;
    
    Sprite player("Player");
    player.draw();
    player.move(10, 5);
    player.draw();
}

// ============================================================
// SECTION 8: POLYMORPHIC CONTAINERS
// ============================================================

void demoPolymorphicContainers() {
    cout << "\n--- Polymorphic Containers ---\n" << endl;
    
    vector<unique_ptr<Animal>> zoo;
    zoo.push_back(make_unique<Dog>());
    zoo.push_back(make_unique<Cat>());
    zoo.push_back(make_unique<Dog>());
    
    cout << "All animals speak:" << endl;
    for (const auto& animal : zoo) {
        animal->speak();
    }
}

// ============================================================
// MAIN
// ============================================================

int main() {
    cout << "╔══════════════════════════════════════╗" << endl;
    cout << "║     POLYMORPHISM - EXAMPLES          ║" << endl;
    cout << "╚══════════════════════════════════════╝" << endl;
    
    demoVirtualBasics();
    demoVirtualVsNonVirtual();
    demoAbstractClasses();
    demoVirtualDestructor();
    demoOverrideFinal();
    demoDynamicCast();
    demoInterfaces();
    demoPolymorphicContainers();
    
    cout << "\n=== Complete ===" << endl;
    return 0;
}
Examples - C++ Tutorial | DeepML