C++ stack allocated object, explicit destructor ca

2019-03-28 13:39发布

I came across a strange use of the destructor while working on an existing library. The destructor of a stack allocated stl vector was being called explicitly, when its the case that that object may need to be used again. These vector objects are a slightly customised version of the stl vector class that have a specialized clear method. In the destructor body there exist two method calls: clear(), _Tidy().

I've been trying to think of a good reason why this destructor is being called rather than just clear but I'm at a loss. Anyone shed any light on why this may be a good idea?

5条回答
The star\"
2楼-- · 2019-03-28 14:18

Large vector?

Wild guess... when clear() is called the vector is usually emptied but the memory not released. That is why there's the pattern

std::vector<T>().swap(vector_to_clear);

to empty the vector for reuse and clear the allocated memory.

Perhaps the original author did not know the pattern and tried to get rid of the allocated memory in this wicked fashion. (I think _Tidy frees the allocated memory)

查看更多
beautiful°
3楼-- · 2019-03-28 14:19

Maybe the original coder cared about where in memory the objects were allocated.

Then the destructor must be called explicitly, as per this discussion.

查看更多
可以哭但决不认输i
4楼-- · 2019-03-28 14:34

Could this class use some kind of placement new method? That's the only time I tend to see explicit destructors in use.

查看更多
Emotional °昔
5楼-- · 2019-03-28 14:35

It's definitely not a good idea. Any operation on an object after the destructor starts running yields undefined behavior.

查看更多
小情绪 Triste *
6楼-- · 2019-03-28 14:39

clear() isn't guaranteed to actually release the allocated storage in the vector; _Tidy() in the MSVC implementation will actually free that storage, so this was probably done as an optimization.

It's an evil thing to do, but you can do it legally (without undefined behavior) so long as the storage is reused by an object of the same type (ignoring cv-qualifiers) that takes up exactly all of the storage:

T automatic;
automatic.T::~T();
new (&automatic) T();

Section 3.8.7 of the C++ standard describes this usage scenario and explains how it's legal; it even includes an example that is similar to the above.

查看更多
登录 后发表回答