Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Multiple inheritance - ambiguous conversions

    SDK Help
    0
    10
    757
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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?

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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 🙂

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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"
              }
              
              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  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.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

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

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

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      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.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        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.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post