我理解在大多数情况下,我们不应该显式地调用析构函数。但是,我看到了C++11 Standard N3485第13.4.5节模板参数中的一个示例:
对具有类模板专门化类型的对象的显式析构函数调用可以显式指定模板参数。示例:模板结构A{ ~A();};void f(A* p,A* q) {p->A::A();// OK:析构函数调用q->A::~A();// OK:析构函数call }
在我看来,在这种情况下,我们可以显式地调用析构函数,您能解释一下为什么吗?在这个例子中,那些析构函数是什么意思?为什么他们是合理的?
另一个问题:
除了在实现placement delete**?**时,我们可以显式调用析构函数的情况是什么?
谢谢。
编辑:我从C++常见问题中发现,我们不应该显式调用局部变量上的析构函数。
发布于 2013-05-23 17:46:30
在我看来,在这种情况下,我们可以显式地调用析构函数,您能解释一下为什么吗?
你是说我们为什么可以?因为语言允许对任何对象进行显式析构函数调用。正如您所说的,它通常会产生未定义的行为,因为大多数对象都会以其他方式被破坏,而破坏任何东西两次(或者更普遍地说是在销毁后访问)是一种未定义的行为。但这只是意味着你不能这样做,而不是语言会阻止你这样做。
或者你是说我们为什么要这么做?因为这就是通过放置新的东西来摧毁一个物体的方法。
在这个例子中,那些析构函数是什么意思?
它们的含义是相同的,并且等同于p->~A();它们调用对象的析构函数。该示例演示了如果愿意,可以在这里提供模板参数。我不知道你为什么要这么做。
除了位置删除之外,我们还可以显式地调用析构函数的情况是什么?
我认为您可以在任何时候调用一个微不足道的析构函数(它什么都不做),但是没有意义。我认为破坏新位置创造的东西是唯一合法的理由。
发布于 2013-05-23 18:15:17
在我看来,在这种情况下,我们可以显式调用析构函数,您能解释一下为什么吗?
因为语言允许它在任何时候调用任何对象的析构函数(假设您有访问权限,例如它不是私有析构函数)。
在本例中,那些析构函数调用的含义是什么?
它只是调用了析构函数。从逻辑上讲,这意味着该对象将被销毁,从那时起应该被视为垃圾,不应该被取消引用或使用。从技术上讲,这意味着该对象处于析构函数所保留的任何状态,对于某些对象来说,这可能与默认构造相同(但您永远不应该依赖它)。
为什么他们是合理的?
有时你需要销毁物体而不释放它们的记忆。这种情况发生在很多类中,如variant/any、各种脚本绑定和反射系统、一些单例实现等。
例如,您可以使用std::aligned_storage为对象分配缓冲区,然后使用placement在该缓冲区中构造对象。您不能对此对象调用delete,因为这将调用析构函数并尝试释放支持它的内存。在这种情况下,必须显式调用析构函数才能正确地解构对象。
除了位置删除之外,我们还可以显式地调用析构函数吗?
没有真正的‘放置删除’,除了对应的运算符放置新的(任何调用delete将隐式调用析构函数,除非编译器调用失败的构造,例如,您的‘布局删除’概念)。
我举了一个上面的例子。另一个例子是std::vector。您可以调用像pop_back()这样的成员函数。这需要销毁向量中的最后一个元素,但它不能使用delete,因为支持对象的内存是必须单独管理的更大缓冲区的一部分。其他许多容器也是如此,如开放寻址哈希表、deque等等。这是您想要使用template typename来显式调用析构函数的一个例子。
这是一个库的用户很少需要的特性,但是像STL这样的低级别库的实现者甚至一些应用程序框架都需要到处使用。
https://stackoverflow.com/questions/16720201
复制相似问题