|
-
February 20th, 2010, 07:40 PM
#1
A question regarding Mulitple Inheritance
Here is a code snippet,
Code:
class A
{
public:
virtual void draw(){cout<<"A"<<endl;}
};
class B
{
public:
virtual void draw(){cout<<"B"<<endl;}
};
class A1 : public A
{
public:
virtual void drawA() = 0;
virtual void draw(){return drawA();}
};
class B1 : public B
{
public:
virtual void drawB() = 0;
virtual void draw(){return drawB();}
};
class D : public A1, public B1
{
public:
virtual void drawA(){cout<<"drawA"<<endl;}
virtual void drawB(){cout<<"drawB"<<endl;}
};
int main()
{
D* pD = new D;
A* pA = pD;
pA->draw();
delete pD;
return 0;
}
Here pA->draw() will call drawA defined in D, why? How'd system know which function should be called, drawA or drawB?
-
February 21st, 2010, 12:30 AM
#2
Re: A question regarding Mulitple Inheritance
When you assign a pointer of D to an pointer of Class A you are implicitly casting a D object to one of Class A thus you are striping the B Part of the inheritance and some of the functionality of Class D.
Implicit cast:
you should always try to minimize casting especially with inheritance because it can lead you to a bunch of trouble
if you use the first object and do this:
Code:
D* pD = new D;
pD->draw();
the compiler will give you an error and will say that draw is ambiguous, it has no way to decide which function to call
the solution for that is to specify the class with the scope resolution operator
something like this:
-
February 21st, 2010, 01:16 AM
#3
Re: A question regarding Mulitple Inheritance
Thanks for your explaination.
 Originally Posted by mrjavoman
When you assign a pointer of D to an pointer of Class A you are implicitly casting a D object to one of Class A thus you are striping the B Part of the inheritance and some of the functionality of Class D.
Implicit cast:
you should always try to minimize casting especially with inheritance because it can lead you to a bunch of trouble
if you use the first object and do this:
Code:
D* pD = new D;
pD->draw();
the compiler will give you an error and will say that draw is ambiguous, it has no way to decide which function to call
the solution for that is to specify the class with the scope resolution operator
something like this:
-
February 22nd, 2010, 12:40 AM
#4
Re: A question regarding Mulitple Inheritance
 Originally Posted by mrjavoman
When you assign a pointer of D to an pointer of Class A you are implicitly casting a D object to one of Class A thus you are striping the B Part of the inheritance and some of the functionality of Class D.
Implicit cast:
you should always try to minimize casting especially with inheritance because it can lead you to a bunch of trouble
This is not true. Casting up is routinely done and is essential for any polymorphic code to work.
And this is casting of pointers and not objects. So, no object slicing takes place either.
if you use the first object and do this:
Code:
D* pD = new D;
pD->draw();
the compiler will give you an error and will say that draw is ambiguous, it has no way to decide which function to call
the solution for that is to specify the class with the scope resolution operator
something like this:
Yes, that is true if he is calling Draw using pD, but he is calling it using pA, which is perfectly legal.
Here pA->draw() will call drawA defined in D, why? How'd system know which function should be called, drawA or drawB?
When you cast up, the compiler is going to treat the object D as object A. And since this function is virtual, it will point to the most recent override which is A1: raw, which in turn calls virtual function DrawA and which points to the most recent override of DrawA which is D: rawA.
So, that is why A1: raw gets called first followed by D: rawA.
-
February 23rd, 2010, 02:48 AM
#5
Re: A question regarding Mulitple Inheritance
 Originally Posted by rohshall
Casting up is routinely done and is essential for any polymorphic code to work.
Yeah you are right, casting is routinely done for polymorphic code but I don't necessarily agree with it being essential
the reason I'm saying this is that when you do this:
Code:
D* pD = new D;
A* pA = pD;
you end up with the D and A pointers pointing to the same object
which as you may know is a behavior that can lead to problems
correct me if I am wrong but I think a better way of writing polymorphic code would be to declare and allocate only one object, thus minimizing the need for casting
Code:
A* pA = NULL;
pA = new D;
//or just
A* pA = new D;
now you would only have one address to worry about which would minimize risk of having your pointer being used where it shouldn't
 Originally Posted by rohshall
And this is casting of pointers and not objects. So, no object slicing takes place either.
I believe object slicing does take place in this example, the second question was
How'd system know which function should be called, drawA or drawB?
and even thought pA is perfectly legal it can't access drawB because Class D inherits from both A1 and B1 and once you cast up to Base class A, like you said, the compiler is going to treat the object D as object A and Class A doesn't know anything about the B hierarchy only Class D does.
I hope I was able to clarify what I meant and thanks for the input
-
February 23rd, 2010, 04:33 AM
#6
Re: A question regarding Mulitple Inheritance
How can there be object slicing when no objects are being copied?
Also, the great thing about virtual functions is that class A does not need to know about the inheritance hierachy.
I'm pretty sure you can even dynamically cast between a pointer to A1 and a pointer to B1 !
-
February 23rd, 2010, 05:09 AM
#7
Re: A question regarding Mulitple Inheritance
 Originally Posted by Zaccheus
I'm pretty sure you can even dynamically cast between a pointer to A1 and a pointer to B1 !
That's a so called crosscast and it's possible using a dynamic_cast.
Note however that this involves an implicit downcast so it should be avoided because it's not typesafe (cannot be verified at compiletime so it can fail at runtime).
-
February 25th, 2010, 10:05 AM
#8
Re: A question regarding Mulitple Inheritance
 Originally Posted by nuzzle
That's a so called crosscast and it's possible using a dynamic_cast.
you guys are right xD my bad, it is posible to access methods from B by using a dynamic_cast
lest see if I get this straight and please correct me if I'm wrong
Rohshall pointed that when casting up you're only casting the pointer, so no slicing of the object is takes place, this is because the pointer still points to the same place in memory and there is no change there right? but from the point of view of the compiler some parts of the class may be hidden because it is now being treated as the class to which the pointer is assigned to and that's when using a dynamic_cast comes in handy although as nuzzle pointed, it should be use with care because it is not typesafe.
You live and you learn...
Last edited by mrjavoman; February 25th, 2010 at 10:09 AM.
Reason: I typed Larry insted of Rohshall
-
February 25th, 2010, 10:58 AM
#9
Re: A question regarding Mulitple Inheritance
dynamic_cast is typesafe as it will give an address of zero if the type being cast to is not a base.
A dynamic_cast without a test for zero is usually not safe.
Code:
Base *p_base;
...
Derived1 *p_derived1 = dynamic_cast<Derived1 *>(p_base);
if (p_derived1 != 0)
{
...
}
Derived2 *p_derived2 = dynamic_cast<Derived2 *>(p_base);
if (p_derived2 != 0)
{
...
}
etc...
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
February 25th, 2010, 11:49 PM
#10
Re: A question regarding Mulitple Inheritance
Rohshall pointed that when casting up you're only casting the pointer, so no slicing of the object is takes place, this is because the pointer still points to the same place in memory and there is no change there right?
Mostly right. :-) The pointer may not point to the same place. (Presumably this depends on the compiler.) If you try the follwing with MS VC++ using LarryChen's original example:
Code:
D* pD = new D;
A* pA = pD;
B* pB = pD;
cout << (int) pD << endl;
cout << (int) pA << endl;
cout << (int) pB << endl;
you'll see the pointer changes between the two upcasts. This is because D contains two v-table pointers, one for the A heirarchy and one for B. The (MS) compiler happened to put A's first.
-
February 26th, 2010, 09:12 AM
#11
Re: A question regarding Mulitple Inheritance
 Originally Posted by GeoRanger
you'll see the pointer changes between the two upcasts.
This is true, but that change is only very slight and the pointer is just pointing to a different part of the overall object.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|