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