CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jul 2005
    Posts
    1,030

    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?

  2. #2
    Join Date
    May 2005
    Location
    San Antonio Tx
    Posts
    44

    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:
    Code:
    A* pA = pD;
    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:
    Code:
    pD->A::draw();

  3. #3
    Join Date
    Jul 2005
    Posts
    1,030

    Re: A question regarding Mulitple Inheritance

    Thanks for your explaination.
    Quote Originally Posted by mrjavoman View Post
    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:
    Code:
    A* pA = pD;
    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:
    Code:
    pD->A::draw();

  4. #4
    Join Date
    Oct 2008
    Location
    Singapore
    Posts
    195

    Re: A question regarding Mulitple Inheritance

    Quote Originally Posted by mrjavoman View Post
    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:
    Code:
    A* pA = pD;
    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:
    Code:
    pD->A::draw();
    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.

  5. #5
    Join Date
    May 2005
    Location
    San Antonio Tx
    Posts
    44

    Re: A question regarding Mulitple Inheritance

    Quote Originally Posted by rohshall View Post
    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

    Quote Originally Posted by rohshall View Post
    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

  6. #6
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    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 !
    My hobby projects:
    www.rclsoftware.org.uk

  7. #7
    Join Date
    May 2009
    Posts
    2,413

    Re: A question regarding Mulitple Inheritance

    Quote Originally Posted by Zaccheus View Post
    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).

  8. #8
    Join Date
    May 2005
    Location
    San Antonio Tx
    Posts
    44

    Re: A question regarding Mulitple Inheritance

    Quote Originally Posted by nuzzle View Post
    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

  9. #9
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    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

  10. #10
    Join Date
    Mar 2006
    Posts
    151

    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.

  11. #11
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: A question regarding Mulitple Inheritance

    Quote Originally Posted by GeoRanger View Post
    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.
    My hobby projects:
    www.rclsoftware.org.uk

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured