主动调用析构函数

4

本文内容包括:

C++指针:如何在不更改地址的情况下更改内容?

用户Eric Postpischil提出了一个回答,其中他主动调用了一个类的析构函数。 这是合法的吗?这被认为是良好的编程实践吗?

我之所以问,是因为我的其中一门课上讲师说这是禁止的,我们永远不能这样做,他错了吗?

虽然该文章中的问题和回答本身很有趣,但它并不是我想要的答案。


6
肯定不是被禁止的。但只有在使用placement new时你才需要这样做。 - chris
我不知道它是否被明确禁止,但这是一种高级技术,可能只适用于非常专业的情况。感谢您链接到那个问题。我之前并不知道placement-new。 - paddy
2
这是每个分配器的核心部分。标准甚至有一个专门的部分关于伪析构函数,只是为了方便手动调用析构函数。 - Kerrek SB
1
可能是 Is calling destructor manually always a sign of a bad design? 的重复问题。 - Jesse Good
感谢大家的评论,我一定会记在心里。 - Ravid Goldenberg
显示剩余2条评论
2个回答

5
好的,像创建动态对象的过程一样,可以将其“拆解”为两个阶段:原始内存分配和实际初始化(例如通过放置new调用构造函数),销毁动态对象的过程也可以被“拆解”为两个阶段:实际反初始化(析构函数调用)和原始内存释放(正如您所见,这两个过程是镜像对称的)。
在您想使用自己的原始内存分配/释放机制的情况下,这非常有用。尽管在许多情况下,您可以通过重载 operator new/delete 来实现所需的效果,但在某些情况下,它并不够灵活,您可能更喜欢明确地执行上述步骤。
因此,这里是直接调用析构函数的一个有用示例。还有许多其他情况。是的,它是完全合法的。
当您的班级老师说您不应该这样做时,他/她可能意味着您应该在当前课程范围内避免使用它。随着学习的进展,您会理解许多“您永远不应该这样做”的技巧实际上是属于“如果您知道您在做什么,请这样做”的有用技术。当然,您不应滥用此技术,因为它确实是一种低级技巧。
附注:这个语法正式称为伪析构函数调用,因为它有点像允许您“调用”不存在的析构函数。
typedef int INT;

INT i;
i.~INT(); // <- legal code, pseudo-destructor call, no op

上述是合法的C++代码,尽管INT不是类类型,因此没有析构函数。(只是不要尝试做i.~int() - 这是非法的。非类类型必须使用别名类型。)


谢谢你的回答,它真的让我理解了这个调用的目的。 - Ravid Goldenberg

2

C++析构函数并不是非法的,也不是被禁止或不好的(当然,如果你做错了就不行了)。所以严格来说,你的老师是错的(尽管他可能只是想传达其他观点)。

最常见的例子是使用动态内存分配的类。简单地说,当在堆栈上调用一个已经为自己分配了内存的类的析构函数时,该内存不会被释放。这意味着堆栈上有保留的内存,但没有任何人引用它,也就是说,你无法访问它。换句话说,你有一个内存泄漏。但是,如果你正确地创建一个析构函数并手动释放内存,你就可以避免这种内存泄漏。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接