明确地调用析构函数

我明白,在大多数情况下,我们不应该明确地调用析构函数。 不过,我从C ++ 11 Standard N3485 Section 13.4.5模板参数中看到了一个例子:

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

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 ++常见问题find,我们不应该显式调用本地variables的析构函数。

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

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

或者你的意思是为什么我们想要? 因为这就是你如何摧毁由新的位置创build的对象。

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

他们都是同样的东西,相当于p->~A() ; 他们调用对象的析构函数。 这个例子说明了如果你愿意,你可以在这里提供模板参数。 我不确定你为什么想要。

除了位置删除之外,我们可以明确调用析构函数的情况是什么?

认为 ,只要你喜欢,你就可以调用一个微不足道的析构函数。 但没有意义。 我认为摧毁一个与新的位置创build的东西是唯一合法的理由。

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

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

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

它只是调用析构函数。 从逻辑上讲,这意味着对象被破坏,应该被认为是垃圾,不应被解除引用或使用。 从技术上讲,这意味着对象处于析构函数离开它的任何状态,对于某些对象而言,这些对象可能与默认构造相同(但绝不应该依赖于此)。

为什么他们是合理的?

有时你需要摧毁物体而不释放自己的记忆。 这种情况发生在很多类,比如variant / any,各种脚本绑定和reflection系统,一些单例实现等等。

例如,您可以使用std::aligned_storage为对象分配一个缓冲区,然后使用placement new在该缓冲区中构造一个对象。 你不能在这个对象上调用delete ,因为那样会调用析构函数,并且试图释放支持它的内存。 在这种情况下,您必须显式调用析构函数来正确地破坏对象。

除了位置删除之外,我们可以明确调用析构函数的情况是什么?

除了相应的操作符放置new外(除了编译器调用失败的构造,例如您的'placement delete'概念), delete任何调用都会隐式地调用析构函数。

上面给出了一个例子。 另一个例子是std::vector 。 你可以调用成员函数像pop_back() 。 这需要销毁向量中的最后一个元素,但不能使用delete因为支持对象的内存是必须单独pipe理的较大缓冲区的一部分。 对于许多其他容器也是如此,例如开放地址哈希表, deque等等。 这是你想要使用template typename来显式调用析构函数的例子。

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