I'm writing a custom Stack container that stores its elements in a fixed-size array:
template<typename T, uint32 TCapacity>
class Stack {
// Member functions omitted
T mData[TCapacity];
uint32 mSize;
};
When an element is popped off the stack, I can just decrement the size. However, I think that if the item is popped off the stack, you'd also expect the destructor to be called on the object.
So, I could manually call the destructor on the object when popping, like so:
void Pop() {
assert(mSize > 0);
mSize--;
mData[mSize].~T();
}
However, when the Stack object itself is destructed, doesn't that cause the destructor to be called again for each object in mData, which could effectively "double destruct" certain elements? It might not be safe to double destruct all types, so this doesn't seem like a good idea.
I guess one alternative approach would be to construct a new object to overwrite the previous object, but that seems kind of inefficient potentially:
void Pop() {
assert(mSize > 0);
mSize--;
mData[mSize] = T();
}
The only other thing I can think of is to have the data array just be an array of bytes (unsigned char) and then deal with the extra complexity of constructing/destructing objects inside that raw memory. Which doesn't seem ideal, but maybe it's the true solution?
Does anyone have insight into a good way to deal with this? I imagine that a built-in container like std::vector also has to deal with this problem (though of course the data memory is allocated from the heap in that case).