What is INSTANCEOF in C++ ?



  • On 01/03/2014 at 02:48, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   13,14,15 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    As my signature tells, I am a C++ amateur.
    I have searched the internet for an answer to this, but I only get hits for IsInstanceOf(), which I understand the purpose of.
    But in the C4D SDK, there is a lot of this INSTANCEOF(), and I wonder what it means, what the purpose is? Some of you experienced C++ guys certainly know what it means.

     **class** BitmapSaverTest : public CommandData
    {
      INSTANCEOF(BitmapSaverTest, CommandData)
      
     **public:**
      **virtual** Bool Execute(BaseDocument* doc);
      
      **static** BitmapSaverTest* Alloc() { **return** gNew BitmapSaverTest; }
    };
    


  • On 01/03/2014 at 03:03, xxxxxxxx wrote:

    You probably noticed in the SDK that for many of the virtual functions in a plugin, such as Message(), it's recommended that at the end of the overriden function you include a call to the parent class's equivalent function. Then in the SDK examples, at the end of their Message() function you see something like this:

      
    return SUPER::Message(node, type, data);   
    

    So where does that SUPER come from? It comes from the INSTANCEOF macro. If you look in c4d_baselist.h you see this:

      
    #define INSTANCEOF(X,Y)                  \   
         public:                                \   
              typedef Y SUPER;                     \   
    

    So when you see:

      
    INSTANCEOF(BitmapSaverTest, CommandData)   
    

    All it does is define CommandData as SUPER, so the call to SUPER in the Message() function of the plugin simply calls CommandData::Message(). If you didn't have this define, you would have to call CommandData::Message explicitly and then it would be different for each plugin type.

    In the end it's a convenient macro so you can always just use SUPER to call functions in the base class rather than the individual plugin base class.

    Steve



  • On 01/03/2014 at 03:24, xxxxxxxx wrote:

    Steve,

    you are a SUPER teacher :)
    Yes, I have often wondered about why SUPER sometimes works, sometimes not. Now I understand the whole thing!

    Originally posted by xxxxxxxx

    If you didn't have this define, you would have to call CommandData::Message explicitly and then it would be different for each plugin type.

    Yes, that is what I have done, so far for C4D plugins. 
    I will see if I can get used to it, provided it does not lead to hard to track down bugs.
    I am used to it though, in C# the operator base is built in:

     _C++_
    SUPER::SomeVirtualFunction();
     _  
    _
     _C#_
    base.SomeVirtualFunction();
    

    So this "SUPER" is something built into, and proprietary, to the C4D machinery, since it is defined in the  c4d_baselist.h file. Is it common to do it like this, or is it a Maxon invention?



  • On 02/03/2014 at 01:35, xxxxxxxx wrote:

    No, SUPER is not built-in or proprietary.

    In this case it's very simple: the typedef makes 'SUPER' an alias for something else. So you see 'SUPER' in the editor, but the compiler sees 'CommandData', thanks to the INSTANCEOF macro. For different types of plugins the compiler would see another base type, so if you have used INSTANCEOF in the plugin class, then when calling the base class you can forget about what type of base class it is - the compiler handles it automatically.

    Note that C++ doesn't have a way to call the base class of a class unless you call the base class explicity (there's no 'super' keyword as in Java, for example).

    You could change 'SUPER' to 'MYBASE' or whatever, it would have the same effect. Or you could use the same technique in software which has nothing to do with C4D. It's just an example of the use of typedef, which is a very useful keyword - worth reading up on it if you're not familiar with it.



  • On 02/03/2014 at 23:09, xxxxxxxx wrote:

    From my personal point of view, don't use INSTANCEOF. It is indeed confusing. Just use

    class MyPlugin : public ObjectData {
        typedef ObjectData SUPER;
    public:
        // ...
    };
    

    which is basically the exact same thing the INSTANCEOF macro expands to. (Yes you got that right,
    the first argument to the INSTANCEOF macro isn't even used)

    Best,
    -Niklas



  • On 02/03/2014 at 23:25, xxxxxxxx wrote:

    Yes, I have seen this typedef in some of the SDK examples.
    Well, I think I will not use any of them. For me, it is crystal clear, with no rooms for confusion at all, to just use the name of the ancestor class directly. No super at all.


Log in to reply