Thread: Castings

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    722

    Ambiguous castings

    Consider this:
    Code:
    class A{
    public:	A(){}
    };
    class B: public A{
    public:	B(){}
    };
    class C: public A{
    public:	C(){}
    };
    class D: public B,public C{
    public:	D(){}
    	operator A(){
    		return *static_cast<B*>(this);
    	}
    };
    
    int main(){
    	D d;
    	A a = d;
    	return 0;
    }
    When I try to assign A a = d I get ambiguity. This is because d can be upcasted to B then A or to C then A. I'm trying to remove the ambiguity with a user-defined conversion, but it's not working. The complier always states ambiguity (MSVC++6.0). How can I slove this? Is the convertion operator well written??

    EDIT:
    If I write a C style casting will it be treated as static_cast or dynamic_cast ?
    Last edited by xErath; 11-05-2004 at 08:26 PM.

  2. #2
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    I'm of the opinion that multiple inheritance should only be used for creation of "interfaces". However if you really must use it, I don't believe you can do multiple inheritance from classes derived from the same base.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    The ambiguity exists whether these are interfaces or not. Plus multiple inheritance IS a C++ feature. Why shoudn't one use it?? I'm not a Java adept that much.
    This is ambiguous:
    A* a = &d;

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Quote Originally Posted by FillYourBrain
    I'm of the opinion that multiple inheritance should only be used for creation of "interfaces". However if you really must use it, I don't believe you can do multiple inheritance from classes derived from the same base.
    Actually you can. iostream is an example of this. iostream is derived from ostream and istream which both derive ios_base.

    A way to get around the ambiguity is to put in another class that dervies from the base but uses protected inheritance.

    (note untested code following)
    Code:
    class A{
    public:A(){}
    };
    
    class B: public A{
    public:B(){}
    };
    
    class C_Mid: protected A{
    public:C(){}
    };
    
    class D: public B,public C_Mid{
    public:D(){}
    operator A(){
    return *static_cast<B*>(this);
    }
    };
    Give something like that a try.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    error C2594: 'argument' : ambiguous conversions from 'class D' to 'const class A &'
    error C2243: 'type cast' : conversion from 'class D *' to 'const class A &' exists, but is inaccessible

    No the protected doesn't work.
    And the ambiguity still exists: cast d to B then A ou to C then A??
    My question is: how can I define a default conversion/casting to prevent ambiguity??

  6. #6
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Going back to your orginal code: Did you even look at all your compiler warnings?

    From g++
    multi.cpp:12: warning: conversion to a base class will never use a type conversion operator
    multi.cpp:12: warning: conversion to a base class will never use a type conversion operator

    multi.cpp: In function `int main()':
    multi.cpp:19: type `const A' is ambiguous base class for type `D'
    multi.cpp:19: warning: unused variable `class A a'
    make: *** [multi] Error 1

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    I'm using MSVC++6, and I don't get those warnings.
    So I can't define a conversion operator to a base class.
    Is there any other way to remove the ambiguity, without using a casting everytime I need to upcast the class ??

    And a initial question:
    If I write a C style casting will it be treated as static_cast or dynamic_cast ?
    A a = (B)d;
    static right??
    Last edited by xErath; 11-06-2004 at 12:10 AM.

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    My main question is this: Why?
    Slicing is generally considered a bad thing.

  9. #9
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    Quote Originally Posted by Thantos
    Actually you can. iostream is an example of this. iostream is derived from ostream and istream which both derive ios_base.
    I stand corrected. I suppose there are just certain things that I've stayed away from because they are problematic.
    Quote Originally Posted by xErath
    Plus multiple inheritance IS a C++ feature. Why shoudn't one use it??
    ugh! Now this is a philosophy I can not agree with. goto is a feature of the language too!
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  10. #10
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    I made simple questions.. Thank you by the "you r stupid" comments.
    I WANT to use multiple inheritance. You can't use it or don't know how to, leave that to yourself, not me.
    Use goto at your will. I don't need it. if I needed I WOULD use goto.
    And 'Why' that's my own motivation/work. I made a simple question.


    And now for something completely diferent!!!!

    If I write a C style casting will it be treated as static_cast or dynamic_cast ? Is it safe?
    A a = (B)d;


    ///////////
    NOTE: sorry for the delayed answer... Weekend way.
    Last edited by xErath; 11-08-2004 at 08:05 PM.

Popular pages Recent additions subscribe to a feed