在处理现有库时,我遇到了析构函数的奇怪用法。当可能需要再次使用该对象时,显式调用了堆栈分配的 stl 向量的析构函数。这些向量对象是 stl 向量类的稍微定制的版本,具有专门的clear
方法。在析构函数体中存在两个方法调用:clear()
, _Tidy()
.
我一直在想一个很好的理由,为什么要调用这个析构函数,而不仅仅是,clear
但我不知所措。任何人都可以解释为什么这可能是一个好主意?
在处理现有库时,我遇到了析构函数的奇怪用法。当可能需要再次使用该对象时,显式调用了堆栈分配的 stl 向量的析构函数。这些向量对象是 stl 向量类的稍微定制的版本,具有专门的clear
方法。在析构函数体中存在两个方法调用:clear()
, _Tidy()
.
我一直在想一个很好的理由,为什么要调用这个析构函数,而不仅仅是,clear
但我不知所措。任何人都可以解释为什么这可能是一个好主意?
clear() 不能保证实际释放向量中分配的存储空间;MSVC 实现中的 _Tidy() 实际上会释放该存储空间,因此这可能是作为优化完成的。
这是一件邪恶的事情,但是只要存储被完全占用所有存储的相同类型的对象(忽略 cv-qualifiers)重用,您就可以合法地这样做(没有未定义的行为):
T automatic;
automatic.T::~T();
new (&automatic) T();
C++ 标准的第 3.8.7 节描述了这种使用场景并解释了它是如何合法的;它甚至包括与上述类似的示例。
这个类可以使用某种放置新方法吗?那是我唯一一次倾向于看到使用显式析构函数。
大向量?
疯狂的猜测......当clear()
被调用时,向量通常被清空但内存没有被释放。这就是为什么有模式
std::vector<T>().swap(vector_to_clear);
清空向量以供重用并清除分配的内存。
也许原作者不知道这种模式,并试图以这种邪恶的方式摆脱分配的内存。(我认为_Tidy
释放分配的内存)
这绝对不是一个好主意。析构函数开始运行后对对象的任何操作都会产生未定义的行为。
也许原始编码器关心对象在内存中的分配位置。
然后必须显式调用析构函数,根据这个讨论。