By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,564 Members | 804 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,564 IT Pros & Developers. It's quick & easy.

some questions about multiple inheritance

P: n/a
Hello,

I've been reading Effective C++ about multiple inheritance, but I
still have a few questions. Can someone give me some help please?

First, it is said that if virtual inheritance is used, then "the
responsibility for initializing a virtual base is borne by the most
derived class in the hierarchy". What does it mean? Initializing
base class is usually done automatically by the compiler, but a
derived class can invoke the base class' constructor. What special
initialization work has to be done by the most derived class? What
about the intermediate classes (those derived classes that aren't at
the end of the hierarchy)? Do they need to do anything to init the
virtual base class and does the most derived class need to do anything
to init the intermediate classes?

Second, it is said that we should try to avoid putting data in a
virtual base class. If we use non-virtual inheritance then there will
be duplicated data members if the base class has data members.
However, once we declare virtual inheritance, then the compiler will
ensure no duplication, is this right? Therefore, it seems ok to me to
put data members into virtual base class. I guess the reason why we
should avoid putting data into a virtual base class is to make
compiler's life easier. In addition, the book also says if we don't
put data into virtual base class, then we "won't have to worry about
oddities in the initialization and assignment rules for such classes".
Could someone tell me what the author means exactly?

Third, if a class D privately inherits from class A and B, do we still
need to use virtual inheritance? If we use non-virtual inheritance,
would there be any data duplication?

Finally, I'm still not sure when multiple inheritance should be used,
any insight will be highly appreciated!

Thanks!
Jess

Jun 26 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Jess wrote:
I've been reading Effective C++ about multiple inheritance, but I
still have a few questions. Can someone give me some help please?
We can try...
First, it is said that if virtual inheritance is used, then "the
responsibility for initializing a virtual base is borne by the most
derived class in the hierarchy". What does it mean?
It means that the compiler generates code such that the virtual base
class' constructor is invoked *not* by the constructor of the class
that directly inherits the virtual base but the most derived one.
Initializing
base class is usually done automatically by the compiler, but a
derived class can invoke the base class' constructor. What special
initialization work has to be done by the most derived class?
Here is an example:

struct vbase {
int i;
vbase(int ii) : i(ii) {}
};

struct a : virtual vbase {
a() : vbase(1) {}
};

struct b : virtual vbase {
b() : vbase(2) {}
};

struct mostderived : a, b {
mostderived() : vbase(42) {} // note 'vbase' initialisation
};

#include <iostream>
int main() {
mostderived m;
std::cout << m.i << std::endl;
}

What do you expect the program to output? The default c-tor of 'a'
makes the 'i' member of 'vbase' 1, 'b' makes it 2. But when the 'm'
object is created in the 'main' function, the 'i' member will be
initialised to 42 because the most derived class is responsible for
initialising the virtual base class.
What
about the intermediate classes (those derived classes that aren't at
the end of the hierarchy)?
What about them? Do you expect to instantiate them independently?
Do they need to do anything to init the
virtual base class and does the most derived class need to do anything
to init the intermediate classes?
Yes, in case you _do_ instantiate them.
Second, it is said that we should try to avoid putting data in a
virtual base class.
Is it said, why?
If we use non-virtual inheritance then there will
be duplicated data members if the base class has data members.
Yes.
However, once we declare virtual inheritance, then the compiler will
ensure no duplication, is this right?
The merging happens between two branches in which *both* base classes
are derived from virtually, like in my example above. Had 'b' not
derived virtually from 'vbase', the duplication would still occur.
Therefore, it seems ok to me to
put data members into virtual base class. I guess the reason why we
should avoid putting data into a virtual base class is to make
compiler's life easier. In addition, the book also says if we don't
put data into virtual base class, then we "won't have to worry about
oddities in the initialization and assignment rules for such classes".
Could someone tell me what the author means exactly?
I believe you could ask the author directly. Isn't there an e-mail
address which you could use?

Anyway, if the hierarchy is more complex, it is generally possible that
somebody makes a mistake and doesn't derive virtually, which means the
duplication can still occur, and have very unpleasant effects. To avoid
the unpleasantness, the author recommends not having any data at all in
the class intended to be the very virtual base.
Third, if a class D privately inherits from class A and B, do we still
need to use virtual inheritance?
To accomplish what?
If we use non-virtual inheritance,
would there be any data duplication?
Data duplication of what?
Finally, I'm still not sure when multiple inheritance should be used,
any insight will be highly appreciated!
Get a hold of a copy of "Modern C++ Design" by Andrei Alexandrescu.
Multiple inheritance is the cornerstone of the "policy-based design".

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 26 '07 #2

P: n/a
Thanks a lot!

On Jun 26, 11:02 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Jess wrote:
I've been reading Effective C++ about multiple inheritance, but I
still have a few questions. Can someone give me some help please?

We can try...
First, it is said that if virtual inheritance is used, then "the
responsibility for initializing a virtual base is borne by the most
derived class in the hierarchy". What does it mean?

It means that the compiler generates code such that the virtual base
class' constructor is invoked *not* by the constructor of the class
that directly inherits the virtual base but the most derived one.
Initializing
base class is usually done automatically by the compiler, but a
derived class can invoke the base class' constructor. What special
initialization work has to be done by the most derived class?

Here is an example:

struct vbase {
int i;
vbase(int ii) : i(ii) {}
};

struct a : virtual vbase {
a() : vbase(1) {}
};

struct b : virtual vbase {
b() : vbase(2) {}
};

struct mostderived : a, b {
mostderived() : vbase(42) {} // note 'vbase' initialisation
};

#include <iostream>
int main() {
mostderived m;
std::cout << m.i << std::endl;
}

What do you expect the program to output? The default c-tor of 'a'
makes the 'i' member of 'vbase' 1, 'b' makes it 2. But when the 'm'
object is created in the 'main' function, the 'i' member will be
initialised to 42 because the most derived class is responsible for
initialising the virtual base class.
What
about the intermediate classes (those derived classes that aren't at
the end of the hierarchy)?

What about them? Do you expect to instantiate them independently?
In your example, if "mostderived" wants to init "a" and "b" explicitly
by calling their constructors, I think "mostderived" can do so, right?
If so, would "a" and "b"'s constructors iniit "vbase" by calling
vbase's constructor?
>
Do they need to do anything to init the
virtual base class and does the most derived class need to do anything
to init the intermediate classes?

Yes, in case you _do_ instantiate them.
I think you mean I can call "a" and "b"'s constructors?
>
Second, it is said that we should try to avoid putting data in a
virtual base class.

Is it said, why?
I don't know why, just mentioned in the book.
>
If we use non-virtual inheritance then there will
be duplicated data members if the base class has data members.

Yes.
However, once we declare virtual inheritance, then the compiler will
ensure no duplication, is this right?

The merging happens between two branches in which *both* base classes
are derived from virtually, like in my example above. Had 'b' not
derived virtually from 'vbase', the duplication would still occur.
Therefore, it seems ok to me to
put data members into virtual base class. I guess the reason why we
should avoid putting data into a virtual base class is to make
compiler's life easier. In addition, the book also says if we don't
put data into virtual base class, then we "won't have to worry about
oddities in the initialization and assignment rules for such classes".
Could someone tell me what the author means exactly?

I believe you could ask the author directly. Isn't there an e-mail
address which you could use?

Anyway, if the hierarchy is more complex, it is generally possible that
somebody makes a mistake and doesn't derive virtually, which means the
duplication can still occur, and have very unpleasant effects. To avoid
the unpleasantness, the author recommends not having any data at all in
the class intended to be the very virtual base.
I see, thanks.
>
Third, if a class D privately inherits from class A and B, do we still
need to use virtual inheritance?

To accomplish what?
To inherit the implemenations.
>
If we use non-virtual inheritance,
would there be any data duplication?

Data duplication of what?
If A and B derive from one base class (vbase) and vbase has data
members. Without inheriting virtually, it seems D can still get
duplicated data.

>
Finally, I'm still not sure when multiple inheritance should be used,
any insight will be highly appreciated!

Get a hold of a copy of "Modern C++ Design" by Andrei Alexandrescu.
Multiple inheritance is the cornerstone of the "policy-based design".
Will try. :)

Thanks,
Jess

Jun 28 '07 #3

P: n/a
Jess wrote:
Thanks a lot!

On Jun 26, 11:02 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>Jess wrote:
>>I've been reading Effective C++ about multiple inheritance, but I
still have a few questions. Can someone give me some help please?

We can try...
>>First, it is said that if virtual inheritance is used, then "the
responsibility for initializing a virtual base is borne by the most
derived class in the hierarchy". What does it mean?

It means that the compiler generates code such that the virtual base
class' constructor is invoked *not* by the constructor of the class
that directly inherits the virtual base but the most derived one.
>> Initializing
base class is usually done automatically by the compiler, but a
derived class can invoke the base class' constructor. What special
initialization work has to be done by the most derived class?

Here is an example:

struct vbase {
int i;
vbase(int ii) : i(ii) {}
};

struct a : virtual vbase {
a() : vbase(1) {}
};

struct b : virtual vbase {
b() : vbase(2) {}
};

struct mostderived : a, b {
mostderived() : vbase(42) {} // note 'vbase' initialisation
};

#include <iostream>
int main() {
mostderived m;
std::cout << m.i << std::endl;
}

What do you expect the program to output? The default c-tor of 'a'
makes the 'i' member of 'vbase' 1, 'b' makes it 2. But when the 'm'
object is created in the 'main' function, the 'i' member will be
initialised to 42 because the most derived class is responsible for
initialising the virtual base class.
>> What
about the intermediate classes (those derived classes that aren't at
the end of the hierarchy)?

What about them? Do you expect to instantiate them independently?

In your example, if "mostderived" wants to init "a" and "b" explicitly
by calling their constructors, I think "mostderived" can do so, right?
Yes, any class deriving from another class initialises the base class
subobject in the constructor initialiser list.
If so, would "a" and "b"'s constructors iniit "vbase" by calling
vbase's constructor?
No, they would not. That's the trick. The virtual base class object
(subobject) is initialised by the most derived class.
>>Do they need to do anything to init the
virtual base class and does the most derived class need to do
anything to init the intermediate classes?

Yes, in case you _do_ instantiate them.

I think you mean I can call "a" and "b"'s constructors?
No, I don't mean you can call them. I mean if you define your own
separate, stand-alone, objects of type 'a' and/or 'b', then *their*
'vbase' subobjects would be initialised in the respective c-tors.

a aa; // aa.vbase::i is 1
b bb; // bb.vbase::i is 2
mostderived m; // m.vbase::i is NEITHER 1 NOR 2
>>[..]
Third, if a class D privately inherits from class A and B, do we
still need to use virtual inheritance?

To accomplish what?

To inherit the implemenations.
Uh... Right. Access specifiers have no effect on who has to init
what virtual base class.
>>
>> If we use non-virtual inheritance,
would there be any data duplication?

Data duplication of what?

If A and B derive from one base class (vbase) and vbase has data
members. Without inheriting virtually, it seems D can still get
duplicated data.
Yes. I thought you were talking of something else.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 28 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.