Multiple inheritance

J

junw2000

In the following code:

#include <iostream>

using namespace std;

class V {
private:
int i;
public:
virtual void f() { cout << "V::f()" << endl;}
};

class A : public V {
void f() {cout << "A::f()" << endl; }
};


class B : public V {
void f() {cout << "B::f()" << endl;} //LINE0
};

class D : public A, public B { };

int main() {
D d; //LINE1

B* bp = &d;

V* vptr = bp;

vptr->f(); //LINE2

}


At LINE1, the object d has two copies of i, one is A::i, one is B::i,
right?

How about f(), does the object d also have two copies of f(), one is
A::f(), one is B::f()?

The output of LINE2 is "B::f()", which means LINE0 is executed. B::f()
is private, why B::f() can be executed in main()?

Thanks a lot.

Jack
 
M

Markus Schoder

In the following code:

#include <iostream>

using namespace std;

class V {
private:
int i;
public:
virtual void f() { cout << "V::f()" << endl;}
};

class A : public V {
void f() {cout << "A::f()" << endl; }
};


class B : public V {
void f() {cout << "B::f()" << endl;} //LINE0
};

class D : public A, public B { };

int main() {
D d; //LINE1

B* bp = &d;

V* vptr = bp;

vptr->f(); //LINE2

}


At LINE1, the object d has two copies of i, one is A::i, one is B::i,
right?
Yes.

How about f(), does the object d also have two copies of f(), one is
A::f(), one is B::f()?

Functions are not per object. There is one function A::f() and one function
B::f() in the whole program.
The output of LINE2 is "B::f()", which means LINE0 is executed. B::f()
is private, why B::f() can be executed in main()?

Since vptr is a V* the only relevant access permissions for this call are
those of class V. Access checking is done only on the static type of the
object.
 
J

junw2000

Thanks.
Functions are not per object. There is one function A::f() and one function
B::f() in the whole program.

If I use virtual base class as below,

class V {
private:
int i;
public:
virtual void f() { cout << "V::f()" << endl;}
};

class A : virtual public V {
void f() {cout << "A::f()" << endl; }
};

class B : virtual public V {
void f() {cout << "B::f()" << endl;} //LINE0
};

class D : public A, public B { };

How many f() are there in the program?

By the way, there is one A::f() in the program. If I have 10 objects of
type A, do the 10 objects share the same f()? How does it work?

Thanks again.

Jack
 
M

Markus Schoder

If I use virtual base class as below,

class V {
private:
int i;
public:
virtual void f() { cout << "V::f()" << endl;}
};

class A : virtual public V {
void f() {cout << "A::f()" << endl; }
};

class B : virtual public V {
void f() {cout << "B::f()" << endl;} //LINE0
};

class D : public A, public B { };

How many f() are there in the program?

V::f(), A::f() and B::f() that is 3.
By the way, there is one A::f() in the program. If I have 10 objects of
type A, do the 10 objects share the same f()? How does it work?

It depends on the implementation. Typically each polymorphic object has a
hidden pointer to a per class data structure which holds a table of
function pointers for the virtual functions (often referred to as the
vtable).
 
K

Kaz Kylheku

How about f(), does the object d also have two copies of f(), one is
A::f(), one is B::f()?

Member functions are not components of a class object. They are simply
functions that have special access with respect to the object, and, if
they are non-static, a special way of receiving the object as a
parameter.

No matter how many copies of a V object you have, and no matter how
many classes inherit V, there is only one V::f function.

The output of LINE2 is "B::f()", which means LINE0 is executed. B::f()
is private, why B::f() can be executed in main()?

What is called by in main() is V::f(), since you have a V * pointer and
are invoking a member function through it. V::f is what the name
lookup resolves to at compile time and that identifier is what is
subject to access control. It's a public identifier, so the call is
allowed.

Control ends up in B::f dynamically, because the object is really a B,
and V::f is a virtual function overriden by B::f. That overriding is
a dynamic, run-time behavior which is not subject to access controls
(and you would not want it to be; that would be silly).
 
D

Duane Hebert

At LINE1, the object d has two copies of i, one is A::i, one is B::i,
right?

How about f(), does the object d also have two copies of f(), one is
A::f(), one is B::f()?

The output of LINE2 is "B::f()", which means LINE0 is executed. B::f()
is private, why B::f() can be executed in main()?


http://www.parashift.com/c++-faq-lite/multiple-inheritance.html

Read about the "diamond" pattern. BTW, you probably
want a virtual dtor in your base class as well.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,163
Latest member
Sasha15427
Top