My own classes in separate file?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 12/02/2003 at 21:34, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   8.012 
    Platform:      
    Language(s) :     C++  ;

    ---------
    Hey, I told you that I'd need help getting back into the swing of C++, especially concerning the SDK. ;0)
    There seems to be trouble creating my own classes (class MyClass) with no derived C4D class and compiling them.  Must my own classes be derived from C4D classes and what would that base class be for general user classes?  As I cannot find any multi-CPP-file projects (I like to put each class into it's own CPP and Header file), some pointers would be greatly appreciated.
    Feeling very stupid after the luxuries of Java, :)
    Robert Templeton



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 12/02/2003 at 23:44, xxxxxxxx wrote:

    Here's the code, what's the problem???
    ErrorDialog.h

        
        
        
        
        ////////////////////////////////////////////////////////////////  
        // ErrorDialog.h  
        ////////////////////////////////////////////////////////////////  
        // Error Modal Dialog class  
        ////////////////////////////////////////////////////////////////  
        // V0.1 2003.02.13 Robert Templeton  
        ////////////////////////////////////////////////////////////////  
        #ifndef _ERRORDIALOG_H_  
        #define _ERRORDIALOG_H_
        
        
        
        
        // Error Dialog Types  
        #define ERROR_RESOURCE   0  
        #define ERROR_POSERNOTFOUND  1  
        #define ERROR_NOREADFILE  2  
        #define ERROR_NOWRITEFILE  3  
        #define ERROR_NOTACR2   4  
        #define ERROR_INVALIDFILE  5  
        #define ERROR_EOF    6  
        #define ERROR_NOOBJECTS   7  
        #define ERROR_GROUPFAIL   8  
        #define ERROR_LISTERROR   9
        
        
        
        
        // CLASS: Error Dialog  
        class ErrorDialog : GeModalDialog  
        {  
         private:  
          INT errtype;  
          String errtext;  
         public:  
          ErrorDialog(INT etype, String etext);  
          Bool CreateLayout();  
        }
        
        
        
        
        #endif //_ERRORDIALOG_H_
        
        
        
    

    ErrorDialog.cpp

        
        
        
        
        ////////////////////////////////////////////////////////////////  
        // ErrorDialog.cpp  
        ////////////////////////////////////////////////////////////////  
        // Error Modal Dialog class  
        ////////////////////////////////////////////////////////////////  
        // V0.1 2003.02.13 Robert Templeton  
        ////////////////////////////////////////////////////////////////
        
        
        
        
        #include "c4d.h"  
        #include "c4d_symbols.h"  
        #include "ErrorDialog.h"
        
        
        
        
        // METHODS: Error Dialog  
        // Constructor  
        ErrorDialog::ErrorDialog(INT etype, String etext)  
        {  
         errtype = etype;  
         errtext = etext;  
        }  
        // Layout Dialog GUI  
        Bool ErrorDialog::CreateLayout()  
        {  
         StatusSetText(GeLoadString(ERROR_STATUS_TEXT));  
         SetTitle(GeLoadString(ERROR_DIALOG_TITLE));  
         AddStaticText(4000,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
         switch(errtype)  
         {  
          case ERROR_RESOURCE:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0, GeLoadString(ERROR_RESOURCE_TEXT),BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_POSERNOTFOUND:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_POSERNOTFOUND_TEXT1),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_POSERNOTFOUND_TEXT2),BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK|DLG_CANCEL);  
           break;  
          case ERROR_NOREADFILE:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_NOREADFILE_TEXT),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,errtext,BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_NOWRITEFILE:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_NOWRITEFILE_TEXT),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,errtext,BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_NOTACR2:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_NOTACR2_TEXT1),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_NOTACR2_TEXT2),BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK|DLG_CANCEL);  
           break;  
          case ERROR_INVALIDFILE:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_INVALIDFILE_TEXT),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,errtext,BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_EOF:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_EOF_TEXT),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,errtext,BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_NOOBJECTS:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_NOOBJECTS_TEXT),BORDER_NONE);  
           AddStaticText(4002,BFH_CENTER|BFV_CENTER,0,0,errtext,BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_GROUPFAIL:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_GROUPFAIL_TEXT),BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          case ERROR_LISTERROR:  
           AddStaticText(4001,BFH_CENTER|BFV_CENTER,0,0,GeLoadString(ERROR_LISTERROR_TEXT),BORDER_NONE);  
           AddStaticText(4003,BFH_CENTER|BFV_CENTER,0,0,"",BORDER_NONE);  
           AddDlgGroup(DLG_OK);  
           break;  
          default:  
           break;  
         }  
         return TRUE;  
        }  
        
    

    PoserCR2Loader.cpp

        
        
        
        
        ////////////////////////////////////////////////////////////////  
        // PoserCR2Loader.cpp  
        ////////////////////////////////////////////////////////////////  
        // Create a boned figure from the information  
        // contained within a Poser .cr2 file.  
        ////////////////////////////////////////////////////////////////  
        // V0.1 2003.02.13 Robert Templeton  
        ////////////////////////////////////////////////////////////////
        
        
        
        
        // Includes  
        #include "c4d.h"  
        #include "c4d_symbols.h"
        
        
        
        
        #include "ErrorDialog.h"  
        //#include "Config.h"
        
        
        
        
        // CLASS: Poser CR2 Loader  
        class PoserCR2Loader : public CommandData  
        {  
         private:  
          //Config* configuration;  
          //PoserCharacter* character;  
         public:  
          virtual Bool Execute(BaseDocument* doc);  
          Bool CallErrorDialog(INT etype, String etext, Bool getresult);  
          void* CallErrorDialog_Null(INT etype, String extext);  
        };  
        Bool PoserCR2Loader::Execute(BaseDocument* doc)  
        {  
         StatusSetText(GeLoadString(IDS_PLUGIN_NAME));  
         CallErrorDialog(ERROR_EOF, "Hi!", FALSE);  
         // Create configuration storage and retrieve from/set to file  
         /*  
         configuration = new Config;  
         if((configuration != NULL) && configuration->SetPoserPath())  
         {  
          // Get .cr2 file and load/parse/cry  
          character = new PoserCharacter;  
          if(character != NULL)  
           character->Parse();  
         }  
         */  
         StatusClear();  
         return (TRUE);  
        }  
        // Call Error Dialog returning Bool  
        Bool PoserCR2Loader::CallErrorDialog(INT etype, String etext, Bool getresult)  
        {  
         ErrorDialog* d;  
         if ((d = new ErrorDialog(etype, etext)) != NULL)  
         {  
          d->Open(-1,-1);  
          if (getresult) return d->GetResult();  
         }  
         else GePrint("Error creating Dialog");  
         return FALSE;  
        }  
        // Call Error Dialog returning NULL  
        void* PoserCR2Loader::CallErrorDialog_Null(INT etype, String etext)  
        {  
         ErrorDialog* d;  
         if ((d = new ErrorDialog(etype, etext)) != NULL) d->Open(-1,-1);  
         else GePrint("Error creating Dialog");  
         return NULL;  
        }
        
        
        
        
          
        // Plugin Functions  
        Bool PluginStart()  
        {  
         PoserCR2Loader* poserCR2Loader = NULL;
        
        
        
        
         // initialize global resource object  
         if (!resource.Init()) return FALSE;
        
        
        
        
         // create new instance of PoserCR2Loader class  
         if ((poserCR2Loader = new PoserCR2Loader) == NULL)  
         {  
          GePrint(GeLoadString(IDS_PLUGIN_NAME) + ": "+GeLoadString(IDS_ERR_CONSTR));  
          return (FALSE);  
         }
        
        
        
        
         // register hook and return  
         return (RegisterCommandPlugin(PLUGIN_ID,  GeLoadString(IDS_PLUGIN_NAME), 0, "pluginicon.tif", GeLoadString(IDS_PLUGIN_DESCR), poserCR2Loader));  
        }
        
        
        
        
        void PluginEnd()  
        {  
        }
        
        
        
        
        Bool PluginMessage(LONG id, void* data)  
        {  
         return (FALSE);  
        }  
        
    

    There exists a "c4d_symbols.h" and "c4d_strings.str".  Until I added the ErrorDialog code, it compiled well.  Now it's nothing but these type of errors:
    Compiling...
    ErrorDialog.cpp
    C:\Program Files\MAXON\CINEMA_4D_R8\Plugins\Kuroyume\PoserCR2Loader\source\ErrorDialog.cpp(16) : error C2143: syntax error : missing ';' before 'PCH creation point'
    PoserCR2Loader.cpp
    C:\Program Files\MAXON\CINEMA_4D_R8\Plugins\Kuroyume\PoserCR2Loader\source\PoserCR2Loader.cpp(18) : error C2143: syntax error : missing ';' before 'PCH creation point'
    C:\Program Files\MAXON\CINEMA_4D_R8\Plugins\Kuroyume\PoserCR2Loader\source\PoserCR2Loader.cpp(52) : error C2248: 'Open' : cannot access public member declared in class 'GeModalDialog'
            ..\..\..\resource\_api\c4d_gui.h(436) : see declaration of 'Open'
    C:\Program Files\MAXON\CINEMA_4D_R8\Plugins\Kuroyume\PoserCR2Loader\source\PoserCR2Loader.cpp(53) : error C2248: 'GetResult' : cannot access public member declared in class 'GeModalDialog'
            ..\..\..\resource\_api\c4d_gui.h(438) : see declaration of 'GetResult'
    C:\Program Files\MAXON\CINEMA_4D_R8\Plugins\Kuroyume\PoserCR2Loader\source\PoserCR2Loader.cpp(62) : error C2248: 'Open' : cannot access public member declared in class 'GeModalDialog'
            ..\..\..\resource\_api\c4d_gui.h(436) : see declaration of 'Open'
    Error executing cl.exe.
    PoserCR2Loader.cdl - 5 error(s), 0 warning(s)

    I can't fix errors like "syntax error : missing ';' before 'PCH creation point'" without knowing why they occur in this case.  This is standard C++ practice to put the class definition into a header and the methods into a .cpp file, include the header in other .cpp files that need it (including the one containing the methods), and add the .cpp to the project.

    If this is the incorrect approach, please feel free to demonstrate the proper way as I cannot seem to find one mentioned.  There will be dozens of classes for this project, so I need to get a good understanding of what is expected.
    Thanks,
    Robert Templeton



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2003 at 00:04, xxxxxxxx wrote:

    First...

        
        
        class ErrorDialog : GeModalDialog
    

    should be

        
        
        class ErrorDialog : public GeModalDialog
    

    otherwise you can't access the members of GeModalDialog (error C2248: 'Open' : cannot access public).
    Second...

        
        
        
        
        }  
        
        
        
        
        
        #endif //_ERRORDIALOG_H_
        
        
        
    

    the end bracket of the class is missing the ';' it should be

        
        
        
        
        };  
        
        
        
        
        
        #endif //_ERRORDIALOG_H_
        
        
        
    

    Your PoserCR2Loader class is ok, just the dialog one is missing it.
    These are easy mistakes when you are out of practice :)
    HTH!



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2003 at 00:09, xxxxxxxx wrote:

    That's what I was talking about.  Yes, I'm outta practice.  Java is nothing like C++ and there is definitely a different approach and mindset between them.
    Now it's time to try a non-derived class.  Wish me luck! :0)
    Thanks,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2003 at 01:04, xxxxxxxx wrote:

    I see that my non-derived custom classes are still giving me hell.  Do I need to derive these from some C4D class, like GeData or BaseContainer?  Otherwise, the class code themselves compiles, but as soon as they referenced by C4D classes, errors.
    Thanks again,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2003 at 01:19, xxxxxxxx wrote:

    Ah. Nevermind.  Figured it out.  I split the PoserCR2Loader class from the PluginXXX()'s, making a header for it.  So, the referenced classes needed header includes in the PoserCR2Loader header (didn't work by putting them before that header in the .cpp).
    Some of it is starting to comeback to me.  Can you tell that it's been several years since programming C++? :)
    I'm liking the AutoAlloc<> feature.   A quick question about my own custom classes: Do they need to be Alloc()/Free()'d or will they get destructed on exit if 'new' is used?
    Back to the grind...
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2003 at 02:07, xxxxxxxx wrote:

    If you use the new operator you must use delete, anything that you allocate and isn't linked to CINEMA in some way you generally have to free, the docs give you info about what CINEMA owns (that doesn't need to be free'd), if it is pure C++ then you are responsible for it (generally).



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2003 at 09:36, xxxxxxxx wrote:

    Okay.  This is the behavior expected.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/02/2003 at 12:59, xxxxxxxx wrote:

    The convenience offered by AutoAlloc<> is offered automatically for classes you create on your own. For example, just as you can write
    > void func()
    > {
    >   AutoAlloc<BaseSelect> bs;
    >   // ...
    > }
    you can do this with your own class, without AutoAlloc<>:
    > void func()
    > {
    >   MyClass mc;
    >   // ...
    > }
    This is called stack, automatic or scoped instatiation. Just note that in both of these cases the object is destructed as soon as it goes out of scoop. So you mustn't store any pointers to it.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/02/2003 at 15:48, xxxxxxxx wrote:

    Okay.  I just haven't settled on the scope of some of the classes being created in other class methods yet. :0)  They may be needed for the entire plugin's duration or just the duration of the method itself.  Still, thanks for the pointer (or lack thereof).  It's been awhile.  Once again, memory allocation is not an issue in Java at all (since everything is created automatically and eventually removed by the GC when it looses scope or references).
    Thanks,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/02/2003 at 01:00, xxxxxxxx wrote:

    Actually it's just as in Java, as long as you don't store any pointers to the stack objects. (Since in Java, as soon as you lose the last pointer, you can just as well consider the object destructed.)
    A good rule of thumb is: use stack objects when you can, and gNew when you have to (for example when the object will be needed outside of the function).



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/02/2003 at 10:00, xxxxxxxx wrote:

    Well, not totally.  In Java, any storage remains until references are lost to it, no matter where it was initiated.  I can create a class that creates an array, pass a reference to the array off to another class, remove references to the first class (thereby deleting the class), and  the array is still valid (even though the class in which it was created is now caput).  In C++, if I do the same for an automatic method variable, I think that the variable will become invalid in the other class since its memory has now been released to NULL.
    There is also no garbage collection in C++.  Automatic variables just die natural deaths at the end of scope.  In Java, a variable can be kept alive as long as the process is running (by keeping a reference to it).  You never have to free memory in Java to avoid memory leaks since the GC cleans up after you.
    Robert


Log in to reply