cpp
examples
examples.cpp⚙️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 = ≻
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;
}