繁体   English   中英

显式调用析构函数

[英]calling destructor explicitly

我知道在大多数情况下,我们不应该显式调用析构函数。 但是,我在 C++11 Standard N3485 Section 13.4.5 Template arguments 中看到了一个例子:

对具有类模板特化类型的对象的显式析构函数调用可以显式指定模板参数。 例子:

 template<class T> struct A { ~A(); }; void f(A<int>* p, A<int>* q) { p->A<int>::~A(); // OK: destructor call q->A<int>::~A<int>(); // OK: destructor call }

在我看来,在这种情况下我们可以明确调用析构函数,你能解释一下为什么吗? 在这个例子中那些析构函数调用是什么意思? 为什么它们是合理的?

另一个问题:

除了实现placement delete之外,还有哪些情况可以显式调用析构函数?

谢谢你。

编辑:我从C++ FAQ 中发现我们不应该在局部变量上显式调用析构函数。

在我看来,在这种情况下我们可以明确调用析构函数,你能解释一下为什么吗?

你的意思是我们为什么可以? 因为该语言允许对任何对象进行显式析构函数调用。 正如你所说,它通常会给出未定义的行为,因为大多数对象都会以其他方式被销毁,并且两次销毁任何东西(或更一般地在销毁后访问它)是未定义的行为。 但这只是意味着你不能这样做,而不是语言会阻止你这样做。

或者你的意思是我们为什么要这样做? 因为这就是您销毁由放置新创建的对象的方式。

在这个例子中那些析构函数调用是什么意思?

它们都是同一个意思,相当于p->~A() 他们调用对象的析构函数。 该示例表明您可以根据需要在此处提供模板参数。 我不确定你为什么想要。

除了放置删除之外,还有哪些情况可以显式调用析构函数?

认为你可以随时调用一个简单的析构函数(一个什么都不做的); 但没有意义。 我认为销毁用placement new 创建的东西是唯一合法的理由。

在我看来,在这种情况下我们可以明确调用析构函数,你能解释一下为什么吗?

因为语言允许随时调用任何对象的析构函数(假设您有权访问,例如它不是私有析构函数)。

在这个例子中那些析构函数调用是什么意思?

它只是调用析构函数。 从逻辑上讲,这意味着该对象已被破坏,从那时起应被视为垃圾,不应取消引用或使用。 从技术上讲,这意味着该对象处于析构函数将其保留的任何状态,对于某些对象,这可能与默认构造相同(但您永远不应该依赖它)。

为什么它们是合理的?

有时您需要销毁对象而不释放它们的内存。 这发生在很多类中,如变体/任何、各种脚本绑定和反射系统、一些单例实现等。

例如,您可以使用std::aligned_storage为对象分配缓冲区,然后使用placement new 在该缓冲区中构造对象。 您不能在此对象上调用delete ,因为这将调用析构函数并尝试释放支持它的内存。 在这种情况下,您必须显式调用析构函数才能正确析构对象。

除了放置删除之外,还有哪些情况可以显式调用析构函数?

除了放置 new 的相应运算符之外,并没有真正的“放置删除”这样的东西(并且对delete任何调用都将隐式调用析构函数,除了编译器因构造失败而调用的那些,例如您的“放置删除”概念)。

我上面举的一个例子。 另一个例子是std::vector 您可以调用诸如pop_back()类的成员函数。 这需要销毁向量中的最后一个元素,但它不能使用delete因为支持对象的内存是必须单独管理的更大缓冲区的一部分。 许多其他容器也是如此,例如开放寻址哈希表、 deque等。 这是您希望使用template typename以显式调用析构函数的示例。

这是一个库的用户很少需要的功能,但是像 STL 甚至一些应用程序框架这样的低级库的实现者将需要在这里和那里使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM