2009-10-28 132 views
6

我在处理现有库时遇到了析构函数的奇怪用法。被分配stl向量的栈的析构函数被明确调用,当它的情况下该对象可能需要再次使用。这些矢量对象是具有专门的clear方法的stl矢量类的稍微定制的版本。在析构函数体中存在两个方法调用:clear(),_Tidy()C++堆栈分配对象,显式析构函数调用

我一直在想为这个析构函数被调用的一个很好的理由,而不仅仅是clear,但我不知所措。任何人都清楚为什么这可能是一个好主意?

+0

你能提供一个代码示例,向量dtor的代码示例,以及它如何被调用? – 2009-10-28 16:43:01

+3

_Tidy()做了什么? – Brian 2009-10-28 16:44:18

+0

向我们展示矢量是如何创建的。 – sbi 2009-10-28 17:07:10

回答

1

这绝对不是一个好主意。析构函数开始运行后对对象的任何操作都会产生未定义的行为。

+0

或者说,析构函数完成后?我想如果你在实例的任何其他地方和超出范围之前在放置new的同一个地方构造另一个实例,这可能是有效的。 – UncleBens 2009-10-28 16:49:51

+0

这些操作包括在作用域结束时自动调用dtor。 – sbi 2009-10-28 17:06:38

+0

@UncleBens:不,一旦析构函数启动,你应该考虑你的对象不再存在...尝试使用基类的析构函数中的虚函数,它实际上使用派生类的堆分配内存......参见我的意思是 :) ? – 2009-10-28 18:51:59

5

这个班可以使用某种placement new方法吗?这是我唯一一次倾向于看到正在使用的显式析构函数。

+0

在我写作的时候打败了我。 ;) – John 2009-10-28 16:47:53

1

也许最初的编码人员关心内存分配对象的位置。

然后必须明确调用析构函数,按照this discussion

+0

这可能是这种情况,因为讨论是关于堆栈分配向量的。 – 2009-10-28 18:53:14

5

大矢量?

疯狂的猜测......当clear()被称为矢量通常是空的,但内存没有释放。这就是为什么有这样的模式

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

清空向量重用和清除分配的内存。

也许原来的作者并不知道这个模式,并试图用这种邪恶的方式摆脱分配的内存。 (我认为_Tidy可以释放分配的内存)

+0

矢量大小不一,但没有太大的。 我很想知道原作者的意图,希望它只是一个误导的内存释放 – Colin 2009-10-28 17:14:14

+0

我的第一个问题是这样的情况是:什么是签入评论? – sbi 2009-10-29 09:26:09

9

clear()不保证实际释放向量中分配的存储空间; MSVC实现中的_Tidy()实际上将释放该存储空间,所以这可能是作为优化完成的。

这是一件很糟糕的事情,但只要存储被相同类型的对象(忽略cv-qualifiers)重用存储并合法地存储所有的存储空间,您就可以合法地执行此操作:

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

C++标准的第3.8.7节描述了这种使用场景并解释了它是如何合法的;它甚至包括一个类似于上面的例子。