Multiple inheritance - ambiguous conversions



  • On 14/08/2013 at 14:28, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R13-R14 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I am rather new to C++, but wanted to take advantage of multiple inheritance.
    But this won't work:

    class Tag_C : public Tag_A, public Tag_B
    {
        public:
    	static NodeData* Alloc (void)
    	{
    		return gNew Tag_C;
    	}
    ....
    

    I get error C2594: 'return' : ambiguous conversions from 'Tag_C *' to 'NodeData *
    How do I deal with this?

    Edited I:
    I guess it is because Tag_A and Tag_B have some functions with the similar names?

    Edited II:
    I think I will drop the whole idea of multiple inheritance, and do it the usual way like in C#.
    Any thoughts?



  • On 14/08/2013 at 20:54, xxxxxxxx wrote:

    The Cinema 4D SDK does not support multiple inheritance.  It is set to 'single inheritance' in the project settings and, believe me, use of multiple inheritance, say in a third-party lib, leads directly to crash city in Cinema 4D. This is why I have dropped using the Point Cloud Library for my current project (they extensively use multiple inheritance).  Avoid it and use a scheme where one class coalesces the properties of two or more classes either by combination or reference to them.



  • On 14/08/2013 at 23:51, xxxxxxxx wrote:

    There's a nice article on why not to use MI at Stack Overflow: http://stackoverflow.com/questions/406081/why-should-i-avoid-multiple-inheritance-in-c

    Steve



  • On 15/08/2013 at 00:23, xxxxxxxx wrote:

    Thanks, this was an important thread for me! There is also a good reason why C# does not support it, I assume.  am used to interfaces, which I use a lot in C#.
    In any case, I have never use MI, and will most likely never use it. I was just tempted to try something new.. Temptation is gone :)



  • On 15/08/2013 at 01:59, xxxxxxxx wrote:

    Ok, I still gave it a thought and a small test.
    Say, is it wrong to use something like this in C4D? It compiles all right, and does not make C4D crash:

    class Foo
    {
        public:
            String MethodA()
            {
                return "A";
            }
    };
      
    class Bar
    {
        public:
            String MethodB()
            {
                return "B";
            }
    };
      
    class FooBar : Foo, Bar
    {
        public:
        String Combined()
        {
            return MethodA() + MethodB();
        }
    };
      
    void SomeOtherClass::TestMultipleInheritance()
    {
    FooBar fooBar; 
    	String test = fooBar.Combined(); 
    	// test is now "AB"
    }
    


  • On 15/08/2013 at 09:18, xxxxxxxx wrote:

    Howdy,

    Well, probably the reason you're not getting any issues with that is because both Foo and Bar classes are base classes.

    Try using this and let's see what happens:

    class Base
    {
        public:
            String MethodCommon()
            {
                return "Common";
            }
    };
      
    class Foo : public Base
    {
        public:
            String MethodA()
            {
                return "A";
            }
    };
      
    class Bar : public Base
    {
        public:
            String MethodB()
            {
                return "B";
            }
    };
      
    class FooBar : Foo, Bar
    {
        public:
        String Combined()
        {
            return MethodA() + MethodB();
        }
    };
      
    void SomeOtherClass::TestMultipleInheritance()
    {
    FooBar fooBar; 
    	String test = fooBar.Combined(); 
    	// test is now "AB"
    }
    

    Adios,
    Cactus Dan



  • On 16/08/2013 at 05:59, xxxxxxxx wrote:

    It will get you into trouble when you have data members in your base class. Then the data would be there twice, one from Foo and one from Bar. The problem here is to initialize and access the right data members.

    The API classes use some strange function pointer magic to forward their method calls to the implementation in the c4d executable. I doubt this could possibly work with any kind of inheritance. Better use composition instead and avoid the headache.

    Edit: Same thing with the actual plugin classes Base***, i guess, though i also don't understand the error in the OP :(. Anyway something like

    class MyTag : public TagData, public Foo, public Bar
    {
       ...
    };

    should be fine if Foo and Bar are really from different class hierarchies and also not API classes.



  • On 16/08/2013 at 06:02, xxxxxxxx wrote:

    Better use composition
    What is composition? I am not familiar with the term



  • On 16/08/2013 at 06:08, xxxxxxxx wrote:

    As very well formulated by the author of the answer in the StackOverflow question spedler posted:

    Originally posted by xxxxxxxx

    Does your object really needs from another? A Car do not need to inherit from an Engine to work, nor from a Wheel. A Car has an Engine and four Wheel.

    Instead of

    class Car : Engine, Wheel {

    };

    You'd write

    class Car {

    Engine m_engine;
            Wheel m_wheels[4];

    };

    In case of the wheels, it would make the least sense to inherit from the Wheel class, because
    the Car itself would represent a single wheel, but there need to be four wheels for a single car.



  • On 16/08/2013 at 06:09, xxxxxxxx wrote:

    class Foo;
    class Bar;

    Composition:
    class FooBar
    {
    Foo foo;
    Bar bar;
    };

    Inheritance:
    class FooBar : Foo, Bar
    {
    };

    basically, you add the functionality through class members instead of through inheritance.


Log in to reply