I’m a C++ application developer by trade, but lately I’ve been reading more in-depth about the language. I have a newly found respect for developers of C++ libraries like Qt, ACE and Boost. Hopefully I can continue to focus on applications and steer clear of library development.
Nonetheless, some of the topics that arise in more advanced C++ programming are quite interesting. Once such advanced concept is virtual inheritance. The first time I saw the virtual keyword in the inheritance list of a class in a code example in Lippman’s “Inside the C++ Object Model,” my jaw nearly dropped. I had no idea you could virtually inherit from a base class, nor did I know what it meant.
For those interested, I decided to toy around with the concept and see what happens with virtual inheritance. Take the following code as an example:
#include <iostream>
class A{
public:
virtual void print() {
std::cout << "<A>\n";
}
};
class D : public A {};
class E : public A {};
class F : public D, public E {};
int main(int argc, char* argv[])
{
F *pF = new F();
pF->print();
return 0;
}
This example is a trivial reproduction of the Diamond Problem, where a subclass has multiple parent classes, and both parent classes inherit from the same base class. This is actual a real problem and if you search more about the iostream class in the standard library there should be a wealth of information on the subject.
If we try to compile the above code, the compiler is going to report about its confusion. For example, GNU g++ reports:
casting.cpp: In function `int main(int, char**)’:
casting.cpp:53: error: request for member `print’ is ambiguous
casting.cpp:9: error: candidates are: virtual void A::print()
casting.cpp:9: error: virtual void A::print()
Microsoft’s C++ compiler reports the following:
casting.cpp(53) : error C2385: ambiguous access of ‘print’
1> could be the ‘print’ in base ‘A’
1> or could be the ‘print’ in base ‘A’
1>casting.cpp(53) : error C3861: ‘print’: identifier not found
Neither warning message is very clear if you’re not familiar with the problem I’m afraid. The confusion is that the compiler doesn’t know whether it should use the print() method in the D class hierarchy or if it should use the print() method in the E class hierarchy. F inherits from both hierarchies and the compiler is vexed that we were not more instructive about what we wanted it to produce. The solution is to use virtual inheritance rather than regular public inheritance. Make the following simple change to the code above:
class D : virtual public A {};
class E : virtual public A {};
If you recompile the code, you’ll see the compiler no longer complains, and it hands its work over to the linker to produce an executable that prints “<A>” to your console. By adding the virtual keyword in the inheritance declaration, we are telling the compiler that rather than creating A in both the D and E class hierarchies, it should simply create one A object and share it amongst D and E.
To fulfill our curiosity, what if we override the print() method in E only?
...
class E : virtual public A {
public:
virtual void print() {
std::cout << "\n";
}
};
...
We rightly expect that “<E>” should be printed to the console. One thing I found interesting was that GNU g++ compiles with no warnings or errors whatsoever with the default settings. Microsoft C++, on the other hand, reports:
1>casting.cpp(23) : warning C4250: ‘F’ : inherits ‘E::E::print’ via dominance
1>casting.cpp(19) : see declaration of ‘E::print’
Microsoft kindly warns us that E has taken over the show, and then it produces the executable. I’m sure there is a flag in g++ that would do the same, but a quick search hasn’t turned up anything. The same holds true if D implemented a print() method rather than E. If D and E both implement print() then as expected the compiler becomes confused and lets us know about its problems.
Though virtual inheritance seems intimidating, it is just another way that hierarchy designers can inform the compiler of their design intenions.

