"JKop" <NULL@NULL.NULL> wrote in message
news:aU2id.40747$Z14.15461@news.indigo.ie...[color=blue]
> I'm starting to think that whenever you derive one class from another,
> that
> you should use virtual inheritance *all* the time, unless you have an
> explicit reason not to. I'm even thinking that there shouldn't have been a
> "virtual" keyword for this purpose, but instead, a "nonvirtual" keyword![/color]
Let's look at the drawbacks of using virtual inheritance
- various overheads in object size and performance will be incurred:
slower access to base class members and slower casts (including
implicit ones), and one pointer added to instances for each
base class.
- downcasting will not be possible with static_cast,
but require calls to dynamic_cast
- all subclasses will have to explicitly initialize each
parent class (except where default initialization is required).
The last issue might be the most annoying in terms of code
maintenance, and loss of encapsulation in general.
When using virtual inheritance, a class doesn't control
the initialization of its base classes anymore. This
is an unacceptable drawback in many cases.
....[color=blue]
> In teaching inheritance, you see the common example:[/color]
....[color=blue]
> I'm thinking that one should stick in virtual inheritance *everywhere*,
> unless there's an explicit reason not to. Here's one reason why:[/color]
In teaching inheritance, most authors and instructors say
that multiple inheritance is to be avoided.
In practice, few are the object oriented frameworks that
actually use multiple inheritance (MI) in ways that require
virtual inheritance. Many languages don't even support MI.
Even when using MI, the intent is not always to share
a single instance of the common base classes.
[color=blue]
> class Vehicle {}
>
> class Car : virtual public Vehicle {}
>
> class Boat : virtual public Vehicle {}
>
> class CarBoat : virtual public Car, virtual public Boat {}
>
>
> Here we can see that it's preferrable to use virtual inheritance
> *everywhere* unless you've an explicit reason not to.[/color]
This is the canonical example where virtual inheritance
is needed. But really, it is not such a common occurences.
Most of the uses of MI I've seen in commercial frameworks
don't need virtual inheritance.
[color=blue]
> Even going further:
>
> class Vehicle {}
> class Vehicle_Land : virtual public Vehicle {}
> class Vehicle_Water : virtual public Vehicle {}
> class Vehicle_Air : virtual public Vehicle {}
> class Vehicle_Space : virtual public Vehicle {}
> class Car : virtual public Vehicle_Land {}
> class Motorcycle : virtual public Vehicle_Land {}
> class Boat : virtual public Vehicle_Water {}
> class Plane : virtual public Vehicle_Air {}
> class Helicopter : virtual public Vehicle_Air {}
> class SpaceShuttle : virtual public Vehicle_Space {}
> class CarBoat : virtual public Car, virtual public Boat {}
> class HelicopterMotorcycle : virtual public Helicopter, virtual public
> Motorcycle{}
> class UltimateVehicle : virtual public HelicopterMotorcycle, virtual
> public
> SpaceShuttle {}[/color]
....[color=blue]
> And this is exactly what we want. We've not explicit reason to make *any*
> of
> the inheritances non-virtual.
>
> Any thoughts on this?[/color]
Multiple inheritance here is only relevant for direct
subclasses of "Vehicle". In other derivations, the virtual
inheritance may even have undesirable effects in some
designs. One may want to keep two copies of a common
base class.
[color=blue]
> One more thing, why is it called "virtual" inheritanc? I see no similarity
> whatsoever between *it* and the "virtual" keyword applied to a function.[/color]
C++ designers don't like to add new keywords, so there is a tendency
to overload their meaning. But in both cases, 'virtual' reflects
the idea of the addition of some overhead which introduces
a dynamic run-time aspect that will create some overhead ;)
The key thing is: I do not agree with your points because:
1) Multiple inheritance (in the OOP paradigm) is best avoided altogether
2) Virtual inheritance reduces encapsulation, and requires all base
classes (direct or indirect) to be initialized by each subclass.
3) Even when MI is needed, virtual inheritance is not always desirable.
4) Virtual inheritance, just like virtual functions, is associated
with an overhead which is unnecessary in most cases.
Cheers,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form