4

在这篇文章中:

C++ 指针:更改内容而不更改地址?

用户 Eric Postpischil 提出了一个答案,他主动调用了类的析构函数。合法吗?它被认为是好的编程吗?

我问的原因是,在我的一堂课上,我的老师说这是禁止的,我们永远不应该这样做,他错了吗?

帖子上的问题和答案本身,虽然有趣与我的问题并不真正相关。

4

2 回答 2

5

好吧,就像动态对象的创建过程可以“反汇编”成两个阶段:原始内存分配和实际初始化(例如通过placement-new调用构造函数)一样,销毁动态对象的过程也可以“反汇编”分为两个阶段:实际的反初始化(析构函数调用)和原始内存释放。(如您所见,这两个进程是彼此的镜像。)

这在您想要使用自己的原始内存分配/释放机制的情况下非常有用。诚然,在许多情况下,您可以通过重载来达到预期的效果operator new/delete,但在某些情况下它不够灵活,您可能更愿意显式地执行上述步骤。

因此,这里有一个示例说明直接析构函数调用何时是一项有用的功能。还有很多其他的。是的,这是完全合法的。

当你的班主任说你不应该这样做时,他/她可能是说你现在应该在你当前的课程范围内避免它。随着你学习的进步,你会明白许多“你永远不应该那样做”的技巧实际上是非常有用的技术,属于“如果你知道自己在做什么,那就去做”类别。当然,您不应该滥用这种技术,因为它确实是一种低级技术。

PS这种语法正式称为析构函数调用,因为它允许您“调用”不存在的析构函数

typedef int INT;

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

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

于 2013-06-05T23:42:51.290 回答
2

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

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

于 2013-06-05T22:33:47.107 回答