3 ms·
Maybe I’m misunderstanding, but by virtual base classes you mean base classes with strictly pure abstract methods, that can be used with virtual inheritance? Be
by w0utert 6y ago
Maybe I’m misunderstanding, but by virtual base classes you mean base classes with strictly pure abstract methods, that can be used with virtual inheritance? Because in that case there is a very straightforward and useful use case for them, which is composing interface classes using multiple inheritance.
For example in some piece of graph-based code I’ve been working on recently, all types returned through public interfaces are pure abstract interfaces. There are different reasons for this, one of them being difficulty to automatically wrap the implementation classes themselves to Python and Java with SWIG, because they use CRTP and other template constructs that are fundamentally incompatible with automatic script interface generation. There is a base interface class INode with an implementation class template Node<T>, but there are also derived interface classes that add additional interfaces to INode, such as ICompositeNode for example. Without virtual base classes it is impossible to have an implementation class CompositeNode<T> that derives from both ICompositeNode (for the interface) and Node<T> (for the implementation), because it is ambiguous. Virtual inheritance solves this.
I never considered this a very special or difficult use case, it seems pretty much any kind of component-bases programming using abstract interface classes would require this sooner or later?
- mehrdadn 6y agoCan't you just cast though? Like this: https://gcc.godbolt.org/z/Mq74Bo https://gcc.godbolt.org/z/Mq74Bo I get that it's a bit of an inconvenient workaround, but it doesn't seem impossible to handle? (At least as far as I've thought it through. I might be missing something though.)
- w0utert 6y agoI would have to go back to the code to see what the difference is with your example, but I think the problem was with overload resolution, where the base interface/implementation classes have a function by the same name as the derived interface/implementation classes but with a different signature. The compiler error was already at the declaration site, and not at the point the classes where instantiated. Maybe I'm not even fully grasping the problem myself, but in any case virtual inheritance on the interface classes resolved it ;-S
- scott_s 6y ago> Maybe I’m misunderstanding, but by virtual base classes you mean base classes with strictly pure abstract methods, that can be used with virtual inheritance? No. Virtual base classes come up in multiple inheritance. Consider you have a class Circle. It derives from both Shape and Savable. But Shape and Savable both derive from a parent base class Base. Let's say that Base has some member function, print. Also assume that neither Circle, Shape or Savable have an implementation of print. So when you have a Circle object, and you call print, does it go to Shape::print or Savable::print? If Base is a normal (non-virtual) base class, it's ambiguous. The compiler can't resolve it, as the Circle object literally has two Base instances inside of it: one from Shape and one from Drawable. The inheritance hierarchy has two roots, both of which are an instance of Base. But if Base is a virtual base class, then Circle will only have one instance of Base. The inheritance hierarchy has only one root, which is Base. This is generally called "the diamond problem": https://stackoverflow.com/questions/2659116/how-does-virtual-inheritance-solve-the-diamond-multiple-inheritance-ambiguit https://stackoverflow.com/questions/2659116/how-does-virtual...