Little pointer issue



  • On 27/10/2013 at 03:33, xxxxxxxx wrote:

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

    ---------
    Hi Folks,

    I'm a little lost with the following scenario. I've got an array of a custom class, and I'm wishing to make a pointer to it. What I've done is the following:

      
    CUSTOMCLASS *MyCLass;   
    

    With this pointer, I'm getting an address to an object of the class (is that correct?) in a vector of vectors by:

      
    MyClass = &MyVector;[1][2];   
    

    The above compiles, but I feel a little uneasy with it. Is this correct thus far, or do I need to be using gNew somewhere here?

    The next little hold-up is that the custom class can take an argument. To give this some sense, here's an example of what I can do when a pointer is not used:

      
    CUSTOMCLASS MyCClass;   
    Real bleh = MyCClass(Real);   
    

    So my queries with the above, if anyone can follow it (!!), is do I need to use gNew on the pointer to begin with? Or can I go straight to the address of the class object in the vector?

    Secondly, I'm unable to compile the plugin when I try adding an argument to a pointer like I do to the direct class object above, that is:

      
    CUSTOMCLASS *MyClass;   
    Real bleh = MyClass(Real);   // doesn't compile   
    

    I've done plenty of general pointer searches but not really quite finding something I can relate too when arrays are involved, or when the class can take an argument.

    Could someone give some pointers for the above (pun intended!), or provide some search terms I can go look up that might help a bit in solving the above?

    Hope I've covered my query with some sense! Cheers,

    WP.



  • On 27/10/2013 at 08:01, xxxxxxxx wrote:

    Hi WP,

    it depends on the datatype of MyVector if the below code is correct or not.

    > CUSTOMCLASS* MyClass = &MyVector[1][2];

    For instance in this scenario, it could be declared as

    > CUSTOMCLASS** MyVector;
    >
    > std::vector<std::vector<CUSTOMCLASS>> MyVector;

    And the indecies must be valid of course, eg. you can not access MyVector[1][2] if the array or
    vector is empty.

    ===================================================================

    > CUSTOMCLASS MyClass;
    >
    > Real value = MyClass(Real);

    This does not compile. Well it could with the correct prerequisites, but it simply looks like a weird
    piece of code. Maybe you mean something like the following:

    > CUSTOMCLASS MyClass(42.5);
    >
    > Real value = MyClass;

    This only compiles if CUSTOMCLASS looks something like this:

    > class CUSTOMCLASS {
    >
    >     Real m_v;
    >
    > public:
    >
    >     CUSTOMCLASS(Real v) : m_v(v) {
    >
    >     }
    >
    >     
    >
    >     operator Real () {
    >
    >         return m_v;
    >
    >     }
    >
    >     
    >
    > };

    ===================================================================

    So my queries with the above, if anyone can follow it (!!), is do I need to use gNew on the pointer to begin with? Or can I go straight to the address of the class object in the vector?

    It depends. gNew allocated new memory, but you can as well use already allocated memory. Eg.
    you can easily create a pointer to stack-allocated memory:

    > CUSTOMCLASS MyClass(42.5);
    >
    > CUSTOMCLASS* MyClassPtr = &MyClass;

    Make sure to not free this pointer. You can allocated new memory using gNew (or NewMem since
    Cinema 4D R15) :

    > CUSTOMCLASS* MyClassPtr = gNew MyClass(42.5);

    You need to free this pointer with gDelete. Another option would be to use a container class which
    manages allocation and deallocation for you (eg. std::vector). The std::vector class is not officially
    supported by Maxon in combination with its SDK, here is how you can use a c4d_misc::BaseArray
    (or maxon::BaseArray since Cinema 4D R15) :

    > c4d_misc::BaseArray<CUSTOMCLASS> MyArray;
    >
    > MyArray.Resize(20);
    >
    > for (LONG i=0; i < 20; i++) {
    >
    > MyArray _= CUSTOMCLASS(i * 42);
    >
    > }
    >
    >
    >
    >
    > CUSTOMCLASS* MyClassPtr = &MyArray[4];
    >
    >
    Do not free this pointer.

    ===================================================================

    One last note: Your class and variable naming is very confusing. At least make your variable
    names lowercase in the first place.

    Best,
    -Niklas



  • On 27/10/2013 at 15:04, xxxxxxxx wrote:

    As I tried to explain earlier but my post didn't happen.  In C++ you either personally manage types, including arrays of classes or you use supplementary structures, such as those provided by the STL or the C4D SDK to maintain integrity in the expected types.  If you construct your support around arrayed class instances, you must consider how your access them specifically.  Niklas describes a couple of ways to achieve this.

    From a historical perspective, C++ is an extension of C which had no such structures beyond declared arrays.  In order to access a class instance in an expected array of such, one would either use array notation (

    myarray[i][j].member
    

    , id est) or use pointers to pointers to access individual class instance memory addresses within the class array memory block.



  • On 27/10/2013 at 20:55, xxxxxxxx wrote:

    Hi Niklas and Robert, thanks for following up above.

    Niklas - just to clarify a few things:

    - all the indices are valid in the std::vector I've made - I'm fairly confident those are okie-dokey. The indicies numbers are currently being printed and look like they're withing the vector size limits etc. Also, the class object is able to take an argument, this is deliberate. The class is a custom spline/graph math object. So putting in a X value into the braces (e.g. 22.3), asks the object to calculate and return what the Y equivalent value is at X point (i.e. 22.3). Everything has worked to date on an instance of the object (the math etc is all working, I can return a Y value as well as safely calculate values outside the bounds of the start and end points etc), but just can't get the same thing happening when wanting to use a pointer. The pointer itself is deleted in the deconstructor of the class where the pointer begins at class-level. From what I can see, it's always either NULL or valid (I say valid loosely because the valid side isn't entirely working yet..!) as various if statements 'should' be taking care of it's status.
    - Re: the confusing naming - yeah, sorry about that. I'll try be a bit more friendly with that in future. I've grown to work with my own style of coding, which I appreciate is not always standard c++ or easy for others to see or work with. I'll try remember to work on that one when making future posts!

    Robert: I feel quite comfortable with the std:: library bits and pieces, and to date have used them often. I probably feel more comfortable with them than I do many c4d things. That's not to downput c4d's options, it's just how I've grown into the coding to-date. With regards to stl operations, I adapt to the requirements at the time, so feel I'm flexible in my approach towards these - which I think helps keep the option open to doing something ordinary stl functions may not cover. I think what you mention about accessing the array notation might possibly be what I'm missing/not utilising in my code correctly. Maybe instead of this (if I understand you right) :

      
    CUSTOMCLASS *MyClassPointer = &MyVector;[1][2];   
    

    I need something like this:

      
    CUSTOMCLASS *MyClassPointer = &MyVector;[1][2].assign(); // .assign just example   
    

    So I might dig into that some more. In it's present form, the code stops compiling when I use the following with a pointer "Real value = MyCustomClassPointer(22.3);" whereas that compiles and works fine when the pointer is instead an instance.

    I must go, wind is picking up and I haven't had a sail for a few days!! Thanks again,

    WP.

    p.s. sorry for the long worded post too, I can't help myself sometimes



  • On 28/10/2013 at 03:16, xxxxxxxx wrote:

    OK, I've found a workaround which involves accessing the vectors through another pointer. Makes the code a little messier to work with, but it's doing it's thing for now.

    Will still look into the pointer at some stage and report back if I come up with something that works.

    WP.



  • On 28/10/2013 at 07:49, xxxxxxxx wrote:

    A pointer is a completely different datatype. It doesn't now about the () operator of your the class
    object it points to. You can either invoke the operator directly or dereference the pointer.

    > CUSTOMCLASS * ptr = ...;
    >
    > Real value = (*ptr)(42.5);
    >
    > // or
    >
    > Real value = ptr->operator () (42.5);

    Best,
    -Niklas



  • On 28/10/2013 at 17:50, xxxxxxxx wrote:

    Ah, I was trying to use the ->operator() when validating the pointer, like:

      
    CUSTOMCLASS mypointer = MyVector[1][2].operator()..... // etc   
    

    No wonder I couldn't get that to do anything, I was using it in the wrong place! Thanks Niklas, the pointer is working now and compiling (and not crashing c4d either - which I can be good at).

    So, I'll go back to using the original pointer I wanted to use in the first place now!

    Thanks,

    WP.


Log in to reply