Reputation: 195
I have trouble understanding why virtual inheritance is useful in a situation where we do not meet a problem similar to the Diamond Problem when a class inherits from 2 classes derived from the same base class.
Could someone give me an example or explanation when it is still helpful (or needed even)?
Thanks:)
Upvotes: 3
Views: 192
Reputation: 70094
Yes, in pre-c++11 era, virtual
inheritance was useful to implement final
like mechanism.
// template style may not work with clang++
template<class T> struct Wrap { typedef T type; };
template<class Derived> class Final { // no one should inherit `D` from hereon
Final () {}
friend class Wrap<Derived>::type;
};
class D : virtual Final<D> {}; // `virtual` inheritance
class D2 : public D {}; // if anyone tries to still inherit `D`
int main () {
D d;
D2 d2; // <--- an expected error occurs upon object declaration
}
Refer from Bjarne Stroustrup's page for simpler but limited way: Can I stop people deriving from my class?
Upvotes: 0
Reputation: 519
"useful" is a subjective word. It's useful enough to some people that it's a language feature in C++, but not enough to others that Java doesn't have it. Interfaces are something similar but do not accomplish the same thing.
The common idiom is a mixin. You keep your regular class hierarchy, but you also inherit from another class that provides some additional (mixin?) functionality. So, you don't use it so that your class can behave like its parent, but just for an implementation.
That seems like a useful thing to me. But, that's subjective.
Upvotes: 0
Reputation: 145457
Virtual inheritance isn't really useful when there isn't a potential diamond shape inheritance problem. That problem is what virtual inheritance is all about solving. At cost of weird object layout and having topmost base initialization invoked from most derived class.
The most common practical application of virtual inheritance is for interfaces.
With virtual inheritance you can use the Java technique of inheriting in an implementation.
In C++03 there were additional use cases for virtual inheritance, hacks based on the need for initializing the topmost class from the most derived one.
These use cases included:
Making a class non-inheritable.
Solved by final
in C++11.
Forcing use of a specific most-derived class (templated).
In C++11 covariant functionality, such as a clone
member function, can more easily be added via middle-man inheritance, with C++11 constructor argument forwarding.
Upvotes: 3