473,405 Members | 2,344 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Virtual inheritance...



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!
In teaching inheritance, you see the common example:
class Vehicle {}

class Car : public Vehicle {}

class Boat : public Vehicle {}
But in my opinion, this *most basic* example should be:
class Vehicle {}

class Car : virtual public Vehicle {}

class Boat : virtual public Vehicle {}
I'm thinking that one should stick in virtual inheritance *everywhere*,
unless there's an explicit reason not to. Here's one reason why:
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.
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 {}
Now... "UltimateVehicle" looks like so:
-----------
| Vehicle |
-----------
^ ^ ^
___________| | |______________
/ | \
/ | \
| | |
| | |
---------------- --------------- -----------------
| Vehicle_Land | | Vehicle_Air | | Vehicle_Space |
---------------- --------------- -----------------
^ ^ ^
| | |
| | |
-------------- -------------- ----------------
| Motorcycle | | Helicopter | | SpaceShuttle |
-------------- -------------- ----------------
^ ^ ^
| | |
\ / /
\ / /
\ / /
\ / /
\ / /
------------------------ /
| MotorcycleHelicopter | /
------------------------ /
^ /
| /
\ /
\ /
\ /
\ /
\ /
-------------------
| UltimateVehicle |
-------------------

And this is exactly what we want. We've not explicit reason to make *any* of
the inheritances non-virtual.

Any thoughts on this?
One more thing, why is it called "virtual" inheritanc? I see no similarity
whatsoever between *it* and the "virtual" keyword applied to a function.
-JKop


Jul 22 '05 #1
4 2867
"JKop" <NU**@NULL.NULL> wrote in message
news:aU*******************@news.indigo.ie...
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!
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.

.... In teaching inheritance, you see the common example: .... I'm thinking that one should stick in virtual inheritance *everywhere*,
unless there's an explicit reason not to. Here's one reason why:
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.
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.
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.
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 {} .... And this is exactly what we want. We've not explicit reason to make *any*
of
the inheritances non-virtual.

Any thoughts on this? 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.
One more thing, why is it called "virtual" inheritanc? I see no similarity
whatsoever between *it* and the "virtual" keyword applied to a function.


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
Jul 22 '05 #2
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.

Oh I just realized something (I think):
Just as how an object contains a hidden pointer to a virtual function... as
in:
class Blah
{
private:

char* t;

public:

int k;

virtual int Monkey(double k)
{
return 87;
}
};
An object of "Blah" might look something like the following in memory:

------------------------------------
| Pointer to the function "Monkey" |
------------------------------------
| t |
------------------------------------
| k |
------------------------------------
Well... similarly, if you have the following:
class Ape {}

class Monkey : virtual public Ape { int rent; }
Might an object of "Monkey" look like the following in memory?:
-----------------------------
| Pointer to the Ape object |
-----------------------------
| rent |
-----------------------------
That would explain why it's called "virtual inheritance". Am I right?
-JKop

Jul 22 '05 #3
"JKop" <NU**@NULL.NULL> wrote in message
news:J4*******************@news.indigo.ie...
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.

Oh I just realized something (I think):
Just as how an object contains a hidden pointer to a virtual function...
as
in:


Actually, an object with virtual functions will (typically) store
a hidden pointer to a static *array* of virtual function pointers.
RTTI information is often stored next to the same table.

This way the array is shared by all instances of a class,
and each instance only stores a single pointer for any number
of virtual functions.
Well... similarly, if you have the following:
class Ape {}

class Monkey : virtual public Ape { int rent; }
Might an object of "Monkey" look like the following in memory?:
-----------------------------
| Pointer to the Ape object |
-----------------------------
| rent |
----------------------------- | Instance of "Ape" object | <--- added
-----------------------------

Also, the pointer may actually be an offset to the Ape instance.
That would explain why it's called "virtual inheritance".
Am I right?


The two are not identical, and other implementations are possible,
so this similarity does not really justify using the same name.
hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Jul 22 '05 #4
>Here we can see that it's preferrable to use virtual inheritance
*everywhere* unless you've an explicit reason not to.


I can't see that.

Care to explain why you think it is preferrable?
Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: nenad | last post by:
Wouldn't it be nice if we could do something like this: class Funky{ public: auto virtual void doStuff(){ // dostuff } };
14
by: Bruno van Dooren | last post by:
Hi all, i am having a problems with inheritance. consider the following: class A { public: A(int i){;} };
3
by: Imre | last post by:
Hi! I've got some questions regarding heavy use of virtual inheritance. First, let's see a theoretical situation, where I might feel tempted to use a lot of virtual inheritance. Let's...
3
by: kikazaru | last post by:
Is it possible to return covariant types for virtual methods inherited from a base class using virtual inheritance? I've constructed an example below, which has the following structure: Shape...
12
by: mijobee | last post by:
I'm very new to c++ and just writing some code to learn. I've run into a problem, with a javaish design, and want to know if there is any possible solution without modifying the design. I've read...
5
by: toton | last post by:
Hi, I want a few of my class to overload from a base class, where the base class contains common functionality. This is to avoid repetition of code, and may be reducing amount of code in binary,...
23
by: Dave Rahardja | last post by:
Since C++ is missing the "interface" concept present in Java, I've been using the following pattern to simulate its behavior: class Interface0 { public: virtual void fn0() = 0; };
12
by: Massimo | last post by:
Hi to all, I'm facing a problem in a particularly complex inheritance hierarchy, and I'd like to know what the standard says about it and if my compiler is correct in what it does. I have two...
0
by: =?Utf-8?B?Zmplcm9uaW1v?= | last post by:
Hi all, As I mentioned in a previous thread (see 'Dbghelp, symbols and templates' in microsoft.public.windbg), we created a powerful symbol engine using dbghelp to dump the contents of the stack...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.