Whenever a vector of my objects gets reallocated, the object's destructor is called and it's causing me problems.
struct Object
{
Object(int buffer_ID) : buffer_ID(buffer_ID){ OpenGLCreateBuffer(buffer_ID, somedata);}
~Object() { OpenGLDeleteBuffer(buffer_ID); }
int buffer_ID;
};
int main()
{
std::vector<Object> objArr;
objArr.push_back(1);
objArr.push_back(2); // Destructor is called when reallocating vector
OpenGLDrawBuffer(objArr[0].buffer_ID); // The buffer has been deleted
}
This is really annoying, I don't understand why the destructor is called on an object that's being moved. I've looked around and I'm pretty satisfied that you can't STOP the destructor from being called. With move semantics I think the trick utilised is to copy the contents from the other object, and set any pointers to null, so that when the destructor is called on them and the resources released, delete is just being called on a nullptr.
I first tried to make a copy constructor, and tried to set the other buffer_ID to 0, but this only works if the copy constructor takes a non-const reference, which doesn't seem right. Also, the act of setting the other's variables to null so that delete is then called on null, or null passed to something like in this case OpenGL delete function, seems hacky, doesn't it?
I know I'm going to be told that I can't stop the destructor from being called, so what should I do in the case where the object may get reallocated to another part? The destructor is the best place to be deleting stuff like this I think.
Thanks.
Your class appears to violate the Rule Of Three. Its destructor appears to destroy a resource that wasn't created in its constructor.
Your real problem is that the fundamental design of your class is incompatible with how std::vector
works. When a vector has to reallocate its contents, its going to either copy-construct or move-construct (if the vector's class support move semantics) the existing instances, then destroy all the old class instances. That's how a vector works. That's how it's designed. If your class cannot work like that, you cannot use std::vector
. Using std::list
would be one option, perhaps.
But a better option is to fix your class. Redesign so that it complies with the Rule Of Three. After doing that, further extend your class to add a move constructor, and proper support for move semantics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With