473,545 Members | 289 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Virtual inheritance

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 consecutive layers of diamond-shaped inheritance; the first layer
is declared as using virtual inheritance, while the second one is declared
as *not* using it.

This is what I'd like to have:

Base Base
/ \ / \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
|| ||
D1Middle D2Middle
\ /
\ /
\ /
Last

This is what the compiler actually does:

Base
/ \
D1Base D2Base
\ /
Middle
/ \
D1Middle D2Middle
\ /
Last

If I remove all virtual inheritance, everything goes just fine; if I use it
in the first layer, there seems to be no way of disabling it afterwards.

Does the standard saying anything about this, or is it
implementation-dependant? My compiler is Visual Studio 2005.

Code sample attached.
Thanks
Massimo

Apr 30 '07 #1
12 2346
jg
On Apr 29, 6:53 pm, "Massimo" <bar...@mclink. itwrote:
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 consecutive layers of diamond-shaped inheritance; the first layer
is declared as using virtual inheritance, while the second one is declared
as *not* using it.

This is what I'd like to have:

Base Base
/ \ / \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
|| ||
D1Middle D2Middle
\ /
\ /
\ /
Last

This is what the compiler actually does:

Base
/ \
D1Base D2Base
\ /
Middle
/ \
D1Middle D2Middle
\ /
Last
I think the object of Last will have a single subobject of Base,
not two. The other subobjects are not shared (i.e. there are
two subobjects each for D1Base, D2Base, Middle).

Base
/ / \ \
/ / \ \
/ / \ \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
| |/
D1Middle D2Middle
\ /
\ /
\ /
Last

JG

Apr 30 '07 #2
"jg" <jg****@gmail.c omha scritto nel messaggio
news:11******** **************@ n76g2000hsh.goo glegroups.com.. .
I think the object of Last will have a single subobject of Base,
not two. The other subobjects are not shared (i.e. there are
two subobjects each for D1Base, D2Base, Middle).

Base
/ / \ \
/ / \ \
/ / \ \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
| |/
D1Middle D2Middle
\ /
\ /
\ /
Last
I really don't know, but don't think so, since each and every one of these
classes is (somewhat) a subclass of Base, and so inherits (or seems to
inherit) the virtual inheritance setting.

I'm actually quite sure there's only one Middle object, because the compiler
doesn't complain about method names resolution issues... while it *does*, if
inheritance is made non-virtual.

Anyway, any clue on how to obtain the desidered behaviour (if this is at all
possible)?
Massimo

Apr 30 '07 #3
On Apr 29, 9:25 pm, "Massimo" <bar...@mclink. itwrote:
"jg" <jgu...@gmail.c omha scritto nel messaggionews:1 1************** ********@n76g20 00hsh.googlegro ups.com...
I think the object of Last will have a single subobject of Base,
not two. The other subobjects are not shared (i.e. there are
two subobjects each for D1Base, D2Base, Middle).
Base
/ / \ \
/ / \ \
/ / \ \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
| |/
D1Middle D2Middle
\ /
\ /
\ /
Last

I really don't know, but don't think so, since each and every one of these
classes is (somewhat) a subclass of Base, and so inherits (or seems to
inherit) the virtual inheritance setting.

I'm actually quite sure there's only one Middle object, because the compiler
doesn't complain about method names resolution issues... while it *does*, if
inheritance is made non-virtual.

Anyway, any clue on how to obtain the desidered behaviour (if this is at all
possible)?
The problem is that every class that declares a virtual base class
shares that base class object with every other class that has declared
the same virtual base class. Therefore it is not possible to declare
D1Base and D2Base in such a way that the two pairs of D1Base and
D2Base objects share the same Base object as one another - without
also having them share the same Base object as every other pair of
D1Base and D2Base objects in the hierarchy. In other words, it is
possible to reduce the top of the current inheritance graph to a
single Base object - or three or four Base class objects - but not two
- as the graph is currently structured.

One way to remedy this problem - and to have the two Base objects at
the top of the hierarchy as desired - would be to insert a pair of
"buffer" classes, Base1 and Base2, between the Base and the D1Base and
D2Base objects. D1Base and D2Base would then each inherit from both
Base1 and Base2 as virtual base classes. The rest of the current
inheritance hierarchy would remain the same.

To illustrate. With this change the top level of the inheritance graph
would like this:

Base Base
| |
| |
Base1 Base2
| | | |
| \ / |
| \ / |
| \/ |
| /\ |
| / \ |
| / \ |
| | | |
D1Base D2Base

And the revised class declarations at the top of hierarchy would look
like:

class Base
{
int n;
};

class Base1 : public Base
{
};

class Base2 : public Base
{
};

class D1Base : public virtual Base1, public virtual Base2
{
};

class D2Base : public virtual Base1, public virtual Base2
{
};

The rest of the inheritance hierarchy would remain the same.

Greg

Apr 30 '07 #4
jg wrote:
Base
/ / \ \
/ / \ \
/ / \ \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
| |/
D1Middle D2Middle
\ /
\ /
\ /
Last
If you are going to draw ascii art, it would be a good
idea to use fixed-width font, wouldn't you think? That looks
like gibberish when looked with a fixed-width font.
Using variable-width font to draw ascii art is insane because
it assumes everyone else is using the exact same font as you are.
Apr 30 '07 #5
On Apr 30, 3:53 am, "Massimo" <bar...@mclink. itwrote:
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 consecutive layers of diamond-shaped inheritance; the first layer
is declared as using virtual inheritance, while the second one is declared
as *not* using it.
This is what I'd like to have:
Base Base
/ \ / \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
|| ||
D1Middle D2Middle
\ /
\ /
\ /
Last
Which is impossible in C++.
This is what the compiler actually does:
Base
/ \
D1Base D2Base
\ /
Middle
/ \
D1Middle D2Middle
\ /
Last
That's not what it does given the code you posted. What you're
actually getting is more like.

------Base------
/ / \ \
/ / \ \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
|| ||
D1Middle D2Middle
\ /
\ /
\ /
Last
If I remove all virtual inheritance, everything goes just
fine; if I use it in the first layer, there seems to be no way
of disabling it afterwards.
Virtual inheritance only affects the classes which derive using
it. On the other hand, all instances of all classes which
derive from Base will share a common instance. You can't group,
with two or three different groups of classes sharing a common
instance.

What you might try is making Base, the two DnBase and Middle
templates (without changing anything else), and instantiating
them on eithre D1Middle or D2Middle. By doing this, the 2
Middle, each of the DnBase, and the two Base are formally
different types. This could result in significant code
duplication, of course.
Does the standard saying anything about this, or is it
implementation-dependant? My compiler is Visual Studio 2005.
The standard specifies very precisely what abstract graph you
should end up with. All of the compilers I have access to
(VC++, Sun CC and g++) are conform in this respect, and
generate to diagram I've given with your code.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 30 '07 #6
jg
On Apr 30, 1:39 am, Juha Nieminen <nos...@thanks. invalidwrote:
jg wrote:
Base
/ / \ \
/ / \ \
/ / \ \
D1Base D2Base D1Base D2Base
\ / \ /
Middle Middle
| |/
D1Middle D2Middle
\ /
\ /
\ /
Last

If you are going to draw ascii art, it would be a good
idea to use fixed-width font, wouldn't you think? That looks
like gibberish when looked with a fixed-width font.
Using variable-width font to draw ascii art is insane because
it assumes everyone else is using the exact same font as you are.
Aha, didn't know this would have made you unhappy. Knowing
that I did not choose to do so could probably make you happy
again. :-) Yeah, your point taken !

Apr 30 '07 #7
"Greg Herlihy" <gr****@pacbell .netha scritto nel messaggio
news:11******** **************@ n59g2000hsh.goo glegroups.com.. .
To illustrate. With this change the top level of the inheritance graph
would like this:

Base Base
| |
| |
Base1 Base2
| | | |
| \ / |
| \ / |
| \/ |
| /\ |
| / \ |
| / \ |
| | | |
D1Base D2Base

And the revised class declarations at the top of hierarchy would look
like:

class Base
{
int n;
};

class Base1 : public Base
{
};

class Base2 : public Base
{
};

class D1Base : public virtual Base1, public virtual Base2
{
};

class D2Base : public virtual Base1, public virtual Base2
{
};
This way, there would be two different "n" in Base1 and Base2, and so D1Base
would have *two* n's, as would D2Base. This is not what i'm looking for... I
want D1Base to have *only one* n (here the virtual inheritance need), and
D2Base to also have *only one* n; but I need those two n's to be two
different ones when deriving from both D1Base and D2Base.

I think the only way to obtain this is to *not* derive subsequent classes
from both, but to put a couple of Middle objects inside Last as members;
this is not exactly what I needed, but it will at least work...

But I'm still curious on why the "virtual" setting for the inheritance is...
inherited, even if I've specified "virtual" only when deriving from Base,
and not when deriving subsequent classes. It just seems to have no effect on
subsequent derivations, making it actually redundant.
Massimo

Apr 30 '07 #8
"James Kanze" <ja*********@gm ail.comha scritto nel messaggio
news:11******** **************@ q75g2000hsh.goo glegroups.com.. .
On Apr 30, 3:53 am, "Massimo" <bar...@mclink. itwrote:
>Virtual inheritance only affects the classes which derive using
it.
Why is it in effect when I'm sub-deriving in a non-virtual manner, then?
On the other hand, all instances of all classes which
derive from Base will share a common instance.
You can't group, with two or three different groups of classes
sharing a common instance.
Yes, I've come to understand this.
Is the "virtual" keyword on sub-derivations redundant, then?
>What you might try is making Base, the two DnBase and Middle
templates (without changing anything else), and instantiating
them on eithre D1Middle or D2Middle. By doing this, the 2
Middle, each of the DnBase, and the two Base are formally
different types.
This is a good suggestion; can you elaborate a bit? Specifically, what do
you mean by "instantiating" ? Making DxMiddle a derived class of a
specialized Middle<T>? I think this wouldn't work; actually, before
semplifying it for posting, the real code involved Base, D1Base, D2Base and
Middle being template classes, and D1Middle being derived from
Middle<double>. D2Middle was derived from Middle<doubleto o, and the
purpose of D1Middle and D2Middle being different classes was exactly to be
able to derive (non-virtually!) Last from both of them, so having two
different Middle<doublein side a Last. But I'm stuck with undesidered
virtual inheritance, so members of D1Middle and D2Middle end un accessing
the same data.
Massimo

Apr 30 '07 #9
On Apr 30, 10:33 pm, "Massimo" <bar...@mclink. itwrote:
"James Kanze" <james.ka...@gm ail.comha scritto nel messaggionews:1 1************** ********@q75g20 00hsh.googlegro ups.com...
On Apr 30, 3:53 am, "Massimo" <bar...@mclink. itwrote:
Virtual inheritance only affects the classes which derive using
it.
Why is it in effect when I'm sub-deriving in a non-virtual manner, then?
I don't get what you're trying to say. If you write something
like:

class A : public B {} ;

B is NOT a virtual base. Period, and regardless of anything
else in the program. There will be one instance of B for every
instance of A, always.
On the other hand, all instances of all classes which
derive from Base will share a common instance.
You can't group, with two or three different groups of classes
sharing a common instance.
Yes, I've come to understand this.
Is the "virtual" keyword on sub-derivations redundant, then?
No. Either you inherit virtually, and the keyword is necessary,
or you don't inherit virtually, and the keyword cannot be used.
What you might try is making Base, the two DnBase and Middle
templates (without changing anything else), and instantiating
them on eithre D1Middle or D2Middle. By doing this, the 2
Middle, each of the DnBase, and the two Base are formally
different types.
This is a good suggestion; can you elaborate a bit? Specifically, what do
you mean by "instantiating" ?
Do you know what a template is? Do you know what it means to
instantiate it.
Making DxMiddle a derived class of a
specialized Middle<T>? I think this wouldn't work; actually, before
semplifying it for posting, the real code involved Base, D1Base, D2Base and
Middle being template classes, and D1Middle being derived from
Middle<double>. D2Middle was derived from Middle<doubleto o, and the
purpose of D1Middle and D2Middle being different classes was exactly to be
able to derive (non-virtually!) Last from both of them, so having two
different Middle<doublein side a Last. But I'm stuck with undesidered
virtual inheritance, so members of D1Middle and D2Middle end un accessing
the same data.
The trick is to instantiate one side on D1Middle, and the other
on D2Middle.

Note that there's nothing in the rules which says that a
template has to use the instantiation type. Something like:

template< typename T >
class Base
{
// as before...
} ;

is perfectly legal. The class will behave exactly the same no
matter what type it is instantiated on, *but* it will have a
different type. Once you do this, you can then define the other
classes as:

template< typename T >
class D1Base : public virtual Base< T >
{
// as before...
} ;

template< typename T >
class D2Base : public virtual Base< T >
{
// as before...
} ;

template< typname T >
class Middle : public D1Base< T >, public D2Base< T >
{
// as before...
} ;

class D1Middle : public Middle< D1Middle >
{
// as before...
} ;

class D2Middle : public Middle< D2Middle >
{
// as before...
} ;

class Last : public D1Middle, public D2Middle
{
// as before...
} ;

This will result in the hierarchy you said you wanted, with the
exception that all of the classes on the left side will in fact
be instantiations on D1Middle, and all on the right side will in
fact be instantiations on D2Middle. (Note that this may affect
your external interface. There's no longer any such class a
Base, for example. And it typically means hoisting a lot of
code up into the headers---not necessarily something you want to
do either.)

--
James Kanze (Gabi Software) email: ja*********@gma il.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 1 '07 #10

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

Similar topics

18
2193
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 } };
4
2887
by: JKop | last post by:
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...
14
1898
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
1702
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 suppose, we're creating a little strategy game. In our game, there are Units. A Unit can be either a Human, or a Vehicle. Obviously, Human and Vehicle...
3
4538
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 = base class Triangle, Square = classes derived from Shape Prism = class derived from Shape TriangularPrism, SquarePrism = classes derived from...
12
2641
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 up on virtual inheritance and from my understanding this should work fine but I haven't found any docs that use such a tangled example. The gcc...
5
1971
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, not to get polymorphic behavior. None of them has virtual methods, and are self contained (no destructor at all) thus do not have a chance to have...
23
4582
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; };
0
1299
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 symbols when an exception occurs. The engine is able to dereference and process UDT symbols up to their highest base class. It also supports...
0
7465
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7398
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7805
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7416
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
5969
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4944
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
1
1878
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1013
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
701
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.