cpp

examples

examples.cpp⚙️
/**
 * Virtual Inheritance - Examples
 * Compile: g++ -std=c++17 -Wall examples.cpp -o examples
 */

#include <iostream>
#include <string>
using namespace std;

// ============================================================
// SECTION 1: DIAMOND PROBLEM WITHOUT VIRTUAL
// ============================================================

namespace NonVirtual {
    class Animal {
    public:
        int id = 0;
        Animal() { cout << "  Animal()" << endl; }
    };
    
    class Mammal : public Animal {
    public:
        Mammal() { cout << "  Mammal()" << endl; }
    };
    
    class Bird : public Animal {
    public:
        Bird() { cout << "  Bird()" << endl; }
    };
    
    // Has TWO copies of Animal!
    class Bat : public Mammal, public Bird {
    public:
        Bat() { cout << "  Bat()" << endl; }
    };
}

void demoProblem() {
    cout << "--- Diamond Problem (Non-Virtual) ---\n" << endl;
    
    NonVirtual::Bat bat;
    // bat.id = 5;  // ERROR: ambiguous
    bat.Mammal::id = 5;
    bat.Bird::id = 10;
    
    cout << "  Mammal::id = " << bat.Mammal::id << endl;
    cout << "  Bird::id = " << bat.Bird::id << endl;
    cout << "  (Two different copies!)" << endl;
}

// ============================================================
// SECTION 2: SOLUTION WITH VIRTUAL INHERITANCE
// ============================================================

namespace Virtual {
    class Animal {
    public:
        int id = 0;
        Animal() { cout << "  Animal()" << endl; }
    };
    
    class Mammal : virtual public Animal {
    public:
        Mammal() { cout << "  Mammal()" << endl; }
    };
    
    class Bird : virtual public Animal {
    public:
        Bird() { cout << "  Bird()" << endl; }
    };
    
    // Single copy of Animal
    class Bat : public Mammal, public Bird {
    public:
        Bat() { cout << "  Bat()" << endl; }
    };
}

void demoSolution() {
    cout << "\n--- Virtual Inheritance Solution ---\n" << endl;
    
    Virtual::Bat bat;
    bat.id = 42;  // OK! Single copy
    
    cout << "  id = " << bat.id << endl;
    cout << "  (Single shared copy!)" << endl;
}

// ============================================================
// SECTION 3: CONSTRUCTOR ORDER
// ============================================================

class Base {
public:
    Base() { cout << "  1. Base()" << endl; }
    Base(int x) { cout << "  1. Base(" << x << ")" << endl; }
};

class Left : virtual public Base {
public:
    Left() : Base() { cout << "  2. Left()" << endl; }
};

class Right : virtual public Base {
public:
    Right() : Base() { cout << "  3. Right()" << endl; }
};

class Bottom : public Left, public Right {
public:
    // Most-derived class initializes virtual base
    Bottom() : Base(99), Left(), Right() {
        cout << "  4. Bottom()" << endl;
    }
};

void demoConstructorOrder() {
    cout << "\n--- Constructor Order ---\n" << endl;
    cout << "Creating Bottom:" << endl;
    Bottom b;
}

// ============================================================
// SECTION 4: PRACTICAL EXAMPLE - STREAM CLASSES
// ============================================================

class IOBase {
protected:
    string buffer;
public:
    IOBase() { cout << "  IOBase initialized" << endl; }
    void setBuffer(const string& s) { buffer = s; }
    string getBuffer() const { return buffer; }
};

class InputStream : virtual public IOBase {
public:
    string read() { return "Read: " + buffer; }
};

class OutputStream : virtual public IOBase {
public:
    void write(const string& s) { buffer += s; }
};

class IOStream : public InputStream, public OutputStream {
public:
    IOStream() : IOBase() { }  // Initialize virtual base
};

void demoStreams() {
    cout << "\n--- Stream Example ---\n" << endl;
    
    IOStream io;
    io.write("Hello");
    io.write(" World");
    cout << "  " << io.read() << endl;
}

// ============================================================
// SECTION 5: INTERFACE DIAMOND
// ============================================================

class IBase {
public:
    virtual void identify() = 0;
    virtual ~IBase() = default;
};

class ILeft : virtual public IBase {
public:
    virtual void left() = 0;
};

class IRight : virtual public IBase {
public:
    virtual void right() = 0;
};

class Implementation : public ILeft, public IRight {
public:
    void identify() override { cout << "  I am Implementation" << endl; }
    void left() override { cout << "  Left operation" << endl; }
    void right() override { cout << "  Right operation" << endl; }
};

void demoInterfaces() {
    cout << "\n--- Interface Diamond ---\n" << endl;
    
    Implementation impl;
    impl.identify();
    impl.left();
    impl.right();
}

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

int main() {
    cout << "╔══════════════════════════════════════╗" << endl;
    cout << "║    VIRTUAL INHERITANCE - EXAMPLES    ║" << endl;
    cout << "╚══════════════════════════════════════╝" << endl;
    
    demoProblem();
    demoSolution();
    demoConstructorOrder();
    demoStreams();
    demoInterfaces();
    
    cout << "\n=== Complete ===" << endl;
    return 0;
}
Examples - C++ Tutorial | DeepML