Jump to content

  • Log In with Google      Sign In   
  • Create Account

Maxjen

Member Since 07 Apr 2012
Offline Last Active Mar 25 2014 11:47 AM

Posts I've Made

In Topic: C++ c

23 March 2014 - 09:49 AM

There is an assertion to warn you in debug mode if this is accidentally used. It is a design decision whether the class should actually support this use case where the client code attempts to call removeElement() on arbitrary indices/ID.

Ah, I just overlooked it. I expected it in the removeElement method, but it was in the clear method.

 

It would appear to me that the intention is that a client class would use addElement(), store an index/ID, and then use getElement() when necessary, finally using removeElement() when finished.

Your correct. A warning when I accidentally do something wrong is all I need, I just didn't see that it's already there.

 

I think Container is too generic. To me, it is some kind of handle system, so maybe a name like HandleRepository?

Yes, that's better, thanks!


In Topic: C++ c

23 March 2014 - 08:23 AM

Okay, now I know that you can write unsigned instead of unsigned int. Also thanks for showing how to implement the rule of three. I think there might be a little bug if removeElement is called for an element that isn't used. The value of nextFreeIndex of that element would get lost and be overridden by freeIndex. Maybe an assertion that isUsed() is -1 like you suggested earlier would help here?

 

I agree about the name, though it's hard to think of something new. Maybe just call it Container?


In Topic: C++ c

22 March 2014 - 09:18 PM

Wow, lots of interesting stuff. I didn't even know you could have internal structs. That alone will be very helpful in some other places. It was a bit overwhelming, but I think I understood most of it now (though I wouldn't be able to reproduce it) except the reinterpret cast. I will look that up.

 

I will also look at the code some more and try to adapt as much as possible to improve my coding skills. Thanks for taking the time! You guys are awesome!


In Topic: C++ c

22 March 2014 - 08:48 AM

 fastcall22 told you to use placement new, and I suggested that you change the pointer type from unsigned char to your template type T to get rid of the manual pointer arithmetics. Those are not mutually exclusive; you want placement new and a proper pointer type.

Ah, I didn't know about operator new(). That should make everything a bit cleaner. Learned something again, thanks! smile.png


In Topic: C++ c

22 March 2014 - 07:54 AM

You mentioned that you load everything into a vertex buffer. Are you loading non-trivial objects that has to ensure proper constructor and destructor calls into vertex buffers, or are you just over-engineering a container of primitive types?

I never actually used this class for vertex buffers but initially I started managing memory like this because I needed to upload stuff into the vertex buffer. I later thought it was neat and made it into a class without realizing that it wouldn't work correctly if used with non-trivial objects. To fix that I started this post but it's probably more trouble than it's worth.

 

Make elements a T * instead of unsigned char *. Saves you all that pointer casting and sizeof-calls in your pointer arithmetics.

I did that at first, but I adjusted my code according to fastcall22's second response using placement new.

 

Don't relocate objects with the C memory functions. You need to properly copy construct and release objects, or move the objects with the move constructor if you want to take advantage of the move-mechanics in C++11. For trivial objects, this is equivalent as a memory move, but for objects with side effects when constructing/destructing/moving objects, this is highly important to get right. Also ensure that you don't assign to the new memory; you must construct the object in the new memory since otherwise you'll assign something to an non-constructed object.

I think I am currently not relocating objects with C memory functions. I use placement new to copy construct the old objects. But I just noticed that I forgot to call the destructors of the released objects when relocating.

 

It turns out that I don't need this class. If anything I will make a version only for trivial objects. But I learned plenty about placement new, smart pointers, initialization lists and the rule of three/five, so thanks! I appreciate all the responses.smile.png


PARTNERS