在这篇文章中:
C++ Pointer: changing the contents without changing the address?
用户Eric Postpischil提出了一个答案,他主动调用了类的析构函数。 这合法吗?它被认为是好的编程吗?
我问的原因是,在我的一个班级中,我的老师说这是禁止的,我们不应该这样做,他错了吗?
帖子上的问题和答案本身虽然有趣但与我的问题无关。
答案 0 :(得分:5)
好吧,就像创建动态对象的过程可以“分解”成两个阶段:原始内存分配和实际初始化(例如构造函数通过placement-new调用),破坏动态对象的过程也可以“反汇编”为两个阶段:实际的去初始化(析构函数调用)和原始内存释放。 (如您所见,这两个过程是彼此的镜像。)
当您想要使用自己的原始内存分配/释放机制时,这非常有用。当然,在许多情况下,您可以通过重载operator new/delete
来达到预期效果,但在某些情况下,它不够灵活,您可能更愿意明确执行上述步骤。
因此,这是直接析构函数调用是一个有用功能的一个例子。还有很多其他人。是的,这是完全合法的。
当你的班级老师说你永远不应该这样做时,他/她可能意味着你现在应该在你当前的课程范围内避免它。当你在学习中取得进步时,你会明白许多“你永远不应该这样做”的技巧实际上是非常有用的技术,属于“做那个,如果你知道你在做什么”类别。当然,你不应该滥用这种技术,因为它确实是一种低级技术。
P.S。这种语法正式称为伪 - 析构函数调用,因为它允许您“调用”不存在的析构函数
typedef int INT;
INT i;
i.~INT(); // <- legal code, pseudo-destructor call, no op
以上是合法的C ++代码,尽管INT
不是类类型,因此没有析构函数。 (只是不要尝试i.~int()
- 这是非法的。别名类型名称必须用于非类型。)
答案 1 :(得分:2)
C ++析构函数当然不是非法的,不是禁止或不好的(除非你当然做错了)。所以,是的,严格来说你的老师错了(尽管他可能只是试图得到其他一些观点)。
最常见的例子是使用动态内存分配的类。简单地说,当在一个已经在堆栈上为自己分配内存的类上调用析构函数时,该内存 not 将被取消分配。这意味着堆栈上有内存保留,但没有任何人引用,这意味着你无法得到它。换句话说,你有内存泄漏。但是,如果您正确创建析构函数并手动释放内存,则可以避免内存泄漏。