C++ Tutorial

Class and Object

Reference

Inheritance and Derivation

Polymorphism and Virtual Functions

Operator Overloading

Template

Exception

Object Oriented Advanced

Input/Output Stream

File Operations

Virtual Inheritance And Virtual Base Class in C++

In this tutorial, we will learn about C++ virtual inheritance and virtual base classes. Virtual inheritance is used to solve the diamond problem, which occurs when a class indirectly inherits from a base class multiple times due to multiple inheritance. Virtual inheritance ensures that only one instance of the base class is present in the derived class.

  • Diamond problem:

The diamond problem arises when a class inherits from two classes that both inherit from a common base class. In this situation, the derived class will have multiple instances of the base class, leading to ambiguity and inefficiency.

Here's an example demonstrating the diamond problem:

#include <iostream>

class A {
public:
    void print() {
        std::cout << "Base class A" << std::endl;
    }
};

class B : public A {
};

class C : public A {
};

class D : public B, public C {
};

int main() {
    D obj;
    // obj.print(); // This would result in a compilation error due to ambiguity
    return 0;
}

In the example above, class D inherits from classes B and C, which both inherit from class A. If we try to call the print() function on an object of class D, it would result in a compilation error due to ambiguity, as there are two instances of class A in class D.

  • Virtual inheritance:

To solve the diamond problem, C++ offers virtual inheritance. By declaring the inheritance as virtual, you ensure that there's only one instance of the base class in the derived class. To use virtual inheritance, use the virtual keyword when specifying the inheritance in the intermediate classes.

Here's the previous example modified to use virtual inheritance:

#include <iostream>

class A {
public:
    void print() {
        std::cout << "Base class A" << std::endl;
    }
};

class B : virtual public A {
};

class C : virtual public A {
};

class D : public B, public C {
};

int main() {
    D obj;
    obj.print(); // Output: Base class A
    return 0;
}

By declaring the inheritance of class A in classes B and C as virtual, we have resolved the ambiguity, and class D has only one instance of class A.

  • Constructors in virtual inheritance:

In the case of virtual inheritance, the constructor of the virtual base class is called by the most-derived class's constructor. Intermediate classes do not call the virtual base class's constructor.

#include <iostream>

class A {
public:
    A() {
        std::cout << "Constructor of A" << std::endl;
    }
};

class B : virtual public A {
public:
    B() {
        std::cout << "Constructor of B" << std::endl;
    }
};

class C : virtual public A {
public:
    C() {
        std::cout << "Constructor of C" << std::endl;
    }
};

class D : public B, public C {
public:
    D() {
        std::cout << "Constructor of D" << std::endl;
    }
};

int main() {
    D obj;
    // Output:
    // Constructor of A
    // Constructor of B
    // Constructor of C
    // Constructor of D
    return 0;
}

That's it for our C++ virtual inheritance and virtual base classes tutorial. Virtual inheritance is an essential technique for resolving the diamond problem in C++ multiple inheritance, helping you write cleaner and more efficient code in your object-oriented programs.

  1. C++ virtual inheritance explanation:

    #include <iostream>
    
    class Base {
    public:
        int data = 10;
    };
    
    // Virtual inheritance
    class Derived1 : public virtual Base {
    };
    
    class Derived2 : public virtual Base {
    };
    
    // Ambiguous without virtual inheritance
    class AmbiguousDerived : public Derived1, public Derived2 {
    };
    
    int main() {
        AmbiguousDerived obj;
        // obj.data = 10; // Error: ambiguous, needs qualification
    
        std::cout << "Data: " << obj.Base::data << std::endl;
    
        return 0;
    }
    
    • Virtual inheritance prevents the "diamond problem" by ensuring only one instance of the base class is shared among multiple paths in the inheritance hierarchy.
  2. Virtual base classes in C++ example:

    #include <iostream>
    
    class Base {
    public:
        int data = 10;
    };
    
    // Virtual inheritance
    class Derived1 : public virtual Base {
    };
    
    class Derived2 : public virtual Base {
    };
    
    // No ambiguity with virtual inheritance
    class NotAmbiguousDerived : public Derived1, public Derived2 {
    };
    
    int main() {
        NotAmbiguousDerived obj;
        obj.data = 20; // No ambiguity
    
        std::cout << "Data: " << obj.data << std::endl;
    
        return 0;
    }
    
    • Virtual inheritance resolves ambiguity and allows accessing the shared base class without qualification.