473,396 Members | 1,816 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,396 software developers and data experts.

virtual inheritance question

Hi all,

i am having a problems with inheritance.
consider the following:

class A
{
public:
A(int i){;}
};

class B: virtual public A
{
public:
B(int i) : A(i){;}
};

class C: virtual public B
{
public:
C(int i) : B(i){;} //raises error C2512: 'A::A' : no appropriate
default constructor available
};

can someone tell me why i get that error? it has to do with the fact that B
has virtual inheritance from A. if i make that non-virtual, the error is
gone. what is the impact of the 'virtual' keyword in this situation?

kind regards,
Bruno.

Nov 17 '05 #1
14 1884
Bruno van Dooren wrote:
Hi all,

i am having a problems with inheritance.
consider the following:

class A
{
public:
A(int i){;}
};

class B: virtual public A
{
public:
B(int i) : A(i){;}
};

class C: virtual public B
{
public:
C(int i) : B(i){;} //raises error C2512: 'A::A' : no appropriate
default constructor available
};

can someone tell me why i get that error? it has to do with the fact that B
has virtual inheritance from A. if i make that non-virtual, the error is
gone. what is the impact of the 'virtual' keyword in this situation?


When you use virtual inheritence, you need to initialize each virtual
base class in the most derived class constructor, since you might have
multiple bases that would do the initialisation if this wasn't the case
(e.g. the classic diamond virtual inheritance example). So your C class
constructor needs to initialize the A base object as well as the B one -
B's initialization of A is ignored when creating a C object.

Tom
Nov 17 '05 #2
> (e.g. the classic diamond virtual inheritance example). So your C class
constructor needs to initialize the A base object as well as the B one -
B's initialization of A is ignored when creating a C object.

Tom


thanks. however, this has the followig implications:
please consider a new scenario:

class A
{
public:
A(int i){;}
};

class B: virtual public A
{
public:
B(int i) : A(i){;}
};

class C: virtual public A
{
public:
C(int i) : A(i){;}
};

class D: virtual public B, C
{
public:
D(int i): C(i),B(i),A(i){;}
};

in this case i end up with C and B using the same instance of A.
multiple inheritance is the only scenario in which i can see a use for
virtual inheritance.
looking at it like this, it seems that the only use of the 'virtual' keyword
in inheritance context is to say "whoever inherits from me has to initialize
my base class too"

this meaning seems unrelated to the meaning of virtual in the context of
member functions. is that correct?

kind regards,
Bruno.
Nov 17 '05 #3
Bruno van Dooren wrote:
(e.g. the classic diamond virtual inheritance example). So your C class
constructor needs to initialize the A base object as well as the B one -
B's initialization of A is ignored when creating a C object.

Tom

thanks. however, this has the followig implications:
please consider a new scenario:

class A
{
public:
A(int i){;}
};

class B: virtual public A
{
public:
B(int i) : A(i){;}
};

class C: virtual public A
{
public:
C(int i) : A(i){;}
};

class D: virtual public B, C
{
public:
D(int i): C(i),B(i),A(i){;}
};

in this case i end up with C and B using the same instance of A.


.... when they are subobjects of a D. That's the classic diamond
inheritance example I mentioned. When you create a D object, only D's
initialization of A is used.
multiple inheritance is the only scenario in which i can see a use for
virtual inheritance.

looking at it like this, it seems that the only use of the 'virtual' keyword
in inheritance context is to say "whoever inherits from me has to initialize
my base class too"
For single inheritance, yes - virtual inheritance is really for cases
where multiple inheritance is, or may be in the future, employed. The
standard library uses it for the ios base class of istream and ostream,
to ensure that iostream only has one ios subobject (basic_ prefixes
elided for clarity).
this meaning seems unrelated to the meaning of virtual in the context of
member functions. is that correct?


Yes.

Tom
Nov 17 '05 #4
Bruno van Dooren wrote:
(e.g. the classic diamond virtual inheritance example). So your C
class constructor needs to initialize the A base object as well as
the B one - B's initialization of A is ignored when creating a C
object. Tom
thanks. however, this has the followig implications:
please consider a new scenario:

class A
{
public:
A(int i){;}
};

class B: virtual public A
{
public:
B(int i) : A(i){;}
};

class C: virtual public A
{
public:
C(int i) : A(i){;}
};

class D: virtual public B, C
{
public:
D(int i): C(i),B(i),A(i){;}
};

in this case i end up with C and B using the same instance of A.
multiple inheritance is the only scenario in which i can see a use for
virtual inheritance.


I'd agree with that statement.
looking at it like this, it seems that the only use of the 'virtual'
keyword in inheritance context is to say "whoever inherits from me
has to initialize my base class too"
It does imply that, yes.
this meaning seems unrelated to the meaning of virtual in the context
of member functions. is that correct?


Mostly unrelated - they just re-used the keyword rather than coming up with
yet another one. The way virtual base classes are implemented is not
dissimilar to how virtual functions are implemented, however. Classes that
have virtual bases have a virtual base table, just like they have a virtual
function table. The entries in the virtual base table gives the offset from
the start of the complete object to the corresponding virtual base.

-cd
Nov 17 '05 #5

Carl Daniel [VC++ MVP] wrote:
this meaning seems unrelated to the meaning of virtual in the context of member functions. is that correct?
Mostly unrelated - they just re-used the keyword rather than coming

up with yet another one. The way virtual base classes are implemented is not dissimilar to how virtual functions are implemented, however. Classes that have virtual bases have a virtual base table, just like they have a virtual function table. The entries in the virtual base table gives the offset from the start of the complete object to the corresponding virtual base.


Nonetheless, I find it was a mistake to reuse the same keyword for
something completely different, even if the inner implementation guts
may have some vague relation. One more time, the
"do-not-add-a-new-keyword-for-any-reason-even-a-very-good-one" syndrom
has bitten us!

Arnaud
MVP -VC

Nov 17 '05 #6
Nonetheless, I find it was a mistake to reuse the same keyword for
something completely different, even if the inner implementation guts
may have some vague relation. One more time, the
"do-not-add-a-new-keyword-for-any-reason-even-a-very-good-one" syndrom
has bitten us!

Arnaud
MVP -VC


I had the same feeling, but not the audacity of venting this opinion on a
public forum because i am obviously not a C++ guru or an MVP.
I feel good knowing that i am not alone in this opinion.

we might as well throw every means of transportation on wheels out of the
dictionary and call everything a bycicle:
car == bycicle with 4 wheels and an engine.
moto bike = bycicle with an engine
train == bicyle with lots of wheels, a heavy duty engine, drives on a
predefined track.
....
Nov 17 '05 #7
> > > this meaning seems unrelated to the meaning of virtual in the
context
of member functions. is that correct?


Mostly unrelated - they just re-used the keyword rather than coming

up with
yet another one. The way virtual base classes are implemented is not

dissimilar to how virtual functions are implemented, however.

Classes that
have virtual bases have a virtual base table, just like they have a

virtual
function table. The entries in the virtual base table gives the

offset from
the start of the complete object to the corresponding virtual base.


Nonetheless, I find it was a mistake to reuse the same keyword for
something completely different, even if the inner implementation guts
may have some vague relation. One more time, the
"do-not-add-a-new-keyword-for-any-reason-even-a-very-good-one" syndrom
has bitten us!


In fact, a virtual base class relates to a base class the same way,
as a virtual member function relates to a non-virtual member function.

You can override implementation of a virtual base class in the derived
class.
Often virtual base classes contain pure member functions only.
These member functions are overriden in descendants.
This way you are achieving a construction called interface.
--
Vladimir Nesterovsky
e-mail: vl******@nesterovsky-bros.com
home: www.nesterovsky-bros.com
Nov 17 '05 #8
Vladimir Nesterovsky wrote:
In fact, a virtual base class relates to a base class the same way,
as a virtual member function relates to a non-virtual member function.

You can override implementation of a virtual base class in the derived
class.
Nonsense - there's no such thing as overriding a virutal base class.
Often virtual base classes contain pure member functions only.
These member functions are overriden in descendants.
In which case you're simply overriding virtual functions declared in the
base class (which happens to be virtual). Any non-virtual members in the
virtual base class are still there and cannot be overridden.
This way you are achieving a construction called interface.


Which you can do just fine without the use of virtual base classes (see COM,
for example).

-cd
Nov 17 '05 #9
> > In fact, a virtual base class relates to a base class the same way,
as a virtual member function relates to a non-virtual member function.

You can override implementation of a virtual base class in the derived
class.
Nonsense - there's no such thing as overriding a virutal base class.


struct A
{
virtual void f() { std::cout << "struct A" << std::endl; }
virtual void f2() { std::cout << "struct A" << std::endl; }
};

struct B: public virtual A
{
virtual void f() { std::cout << "struct B" << std::endl; }
virtual void f2() { std::cout << "struct B" << std::endl; }
};

struct C: public virtual A {};

struct D: public C, public virtual B {};

int main()
{
C &c1 = C();
C &c2 = D();

c1.f();
c2.f();
}

From these declarations we can see that ? contains A as its part, however B
substitutes A in the D.
In this sence B overrides A in the D, which is descendant of the C.
Often virtual base classes contain pure member functions only.
These member functions are overriden in descendants.


In which case you're simply overriding virtual functions declared in the
base class (which happens to be virtual). Any non-virtual members in the
virtual base class are still there and cannot be overridden.
This way you are achieving a construction called interface.


Which you can do just fine without the use of virtual base classes (see

COM, for example).


In fact .NET interfaces are closer to a virtual pure base classes than to
other model.
--
Vladimir Nesterovsky
e-mail: vl******@nesterovsky-bros.com
home: www.nesterovsky-bros.com
Nov 17 '05 #10
Vladimir Nesterovsky wrote:
Nonetheless, I find it was a mistake to reuse the same keyword for
something completely different, even if the inner implementation guts
may have some vague relation. One more time, the
"do-not-add-a-new-keyword-for-any-reason-even-a-very-good-one"
syndrom has bitten us!


In fact, a virtual base class relates to a base class the same way,
as a virtual member function relates to a non-virtual member function.

You can override implementation of a virtual base class in the derived
class.
Often virtual base classes contain pure member functions only.
These member functions are overriden in descendants.
This way you are achieving a construction called interface.


On the contrary, virtual inheritance make sense only for base classes that
are not pure interfaces : the whole point of VI is to avoid duplication of
data members : on a pure interface, you've got no data members, so no
duplicates problems. The other effects you may see on function is
side-effect of the "overiding through dominance" rule, but this not the
purpose of VI.

Note that things can become a bit messy when you add delegates/events to the
big picture. For example, I often declare C++ "interfaces" (no
implementation and no "logical" data member) that contain one or more
boost::signal (or LibSigC++ equivalent), because I do consider that the
events that can be raisen are part of an interface. However, this make my
"logical" interfaces physical "classes" (with data members). In such a case,
VI has a meaning even for interfaces, but this is more a deficiency of the
C++ model (lack of events/delegates/closures) than anything else.

Arnaud
MVP - VC
Nov 17 '05 #11
"Vladimir Nesterovsky" <vl******@nesterovsky-bros.com> wrote in message
news:eN**************@TK2MSFTNGP14.phx.gbl...
> In fact, a virtual base class relates to a base class the same way,
> as a virtual member function relates to a non-virtual member function.
>
> You can override implementation of a virtual base class in the derived
> class.
Nonsense - there's no such thing as overriding a virutal base class.

[snipped to save space]

From these declarations we can see that ? contains A as its part, however
B
substitutes A in the D.
In this sence B overrides A in the D, which is descendant of the C.


Not so. B overrides the functions originally declared in A, it does not
override A itself. If your virtual base contains only pure virtual
functions, there's no practical difference. It's when your virtual base
contains data members that the distinction is important.

-cd
Nov 17 '05 #12
> >In fact, a virtual base class relates to a base class the same way,
as a virtual member function relates to a non-virtual member function.
You can override implementation of a virtual base class in the
derived class.
Nonsense - there's no such thing as overriding a virutal base class.

From these declarations we can see that ? contains A as its part,
however B substitutes A in the D.
In this sence B overrides A in the D, which is descendant of the C.


Not so. B overrides the functions originally declared in A, it does not
override A itself. If your virtual base contains only pure virtual
functions, there's no practical difference. It's when your virtual base
contains data members that the distinction is important.


This way one can argue that virtual member functions are not overriden
indeed, but only some values in virtual tables are substituted, and old
implementations are in their places.

If the struct A contains a state and this state is changed in a constructor
of the struct B, or extended in a declaration of the struct B, than other
subobjects see subobject A after its initialization with the struct B. In
this sence B overrides A's state.
--
Vladimir Nesterovsky
e-mail: vl******@nesterovsky-bros.com
home: www.nesterovsky-bros.com

Nov 17 '05 #13
> On the contrary, virtual inheritance make sense only for base classes that
are not pure interfaces


I do not agree with such a categorical assertion.
The whole idea of interfaces in com, java, .net is close to a virtual
inheritance of a pure classes.
--
Vladimir Nesterovsky
e-mail: vl******@nesterovsky-bros.com
home: www.nesterovsky-bros.com
Nov 17 '05 #14
Vladimir Nesterovsky wrote:
This way one can argue that virtual member functions are not overriden
indeed, but only some values in virtual tables are substituted, and
old implementations are in their places.

If the struct A contains a state and this state is changed in a
constructor of the struct B, or extended in a declaration of the
struct B, than other subobjects see subobject A after its
initialization with the struct B. In this sence B overrides A's state.


In C++, the term "overriding" has a well-defined technical meaning. It
applies exclusively to member functions. There is no such thing as
overriding of a class.

--
Gerhard Menzl

#dogma int main ()

Humans may reply by replacing the thermal post part of my e-mail address
with "kapsch" and the top level domain part with "net".
Nov 17 '05 #15

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

Similar topics

9
by: Michael Winter | last post by:
Until about 5 minutes ago, I was happy with my knowledge of virtual functions - then I read "Mixing interface and functional inheritance" posted by Kevin L. earlier today. All of a sudden, I found...
4
by: Sat | last post by:
Hi, I have a simplified version of a problem that I am facing (hope I haven't oversimplified it). This code doesn't work now and I want to find how I can make it work. Can I call the derived...
4
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...
3
by: cyrusNew | last post by:
Hi, sorry if it was already asked, I have a following class diagram A =? A | | B C \ /
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...
2
by: Heinz Ketchup | last post by:
Hello, I'm looking to bounce ideas off of anyone, since mainly the idea of using Multiple Virtual Inheritance seems rather nutty. I chalk it up to my lack of C++ Experience. Here is my...
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; };
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
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
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,...
0
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...
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
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...
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.