析构函数参数

42

《是否可以重载析构函数?》 这篇文章谈到了析构函数的重载。

这引发了一个问题:析构函数可以有参数吗?

我从未使用过或看到过带参数的析构函数。我无法想出使用析构函数参数的原因的例子。


1
你能举个例子说明为什么析构函数应该带参数吗? - Ali1S232
2
你阅读了那个问题的被接受答案中FAQ链接吗? - Mat
嗯...我认为析构函数的参数只有在删除对象有多种方式时才有用。我想这可能偶尔会发生(例如,当删除文件对象时,您可能希望指定是否立即将文件缓冲区刷新到磁盘上)...但是无论如何都有更好的处理方法。带参数的析构函数与堆栈和成员对象结合使用会很麻烦(即在隐式删除时应该在哪里指定参数?) - Jeremy Friesner
@Mat:我没有意识到No是一个链接。C++ FAQ指出析构函数不带任何参数,但我想要更多的引用或参考标准的任何版本。 - Thomas Matthews
@Jeremy:你的理解有误。析构函数不是在你想删除一个对象时调用的函数,而是当一个对象被销毁时自动调用的函数。并不是特指删除,而是销毁。例如,当对象超出范围时,它会被隐式销毁。那么如果存在几个不同的析构函数,应该调用哪一个?你如何指定要调用哪一个? - jalf
显示剩余4条评论
4个回答

53

C++0x 草案 n3290 的第 §12.4 节对析构函数有如下说明:

析构函数

在类定义中,使用可选的函数说明符(7.1.2)后跟 ˜,然后是析构函数的类名,最后是一个空参数列表的特殊声明语法来声明析构函数。

(强调添加)

因此,析构函数不需要参数。(2003 标准与上述段落的措辞完全相同。)


1
为什么需要参数?Andrei(如果我没记错的话)曾经提出了一个可选析构函数参数,它可以告诉你对象是否由于异常处理而被销毁。这将允许更多用户安全的作用域保护对象,例如用于事务操作。有了这样的支持,客户端代码编写者就不必记住在作用域末尾调用某个cancel()方法了。 - Cheers and hth. - Alf
2
分配和释放函数不遵循构造函数和析构函数的模式:分配函数可以有额外的参数(放置形式),如果有,则必须有相应的具有相同额外参数的释放函数。仅在构造失败时才调用它。无法通过 delete 调用它。我一直想知道这种机制的意义所在。 - Cheers and hth. - Alf
3
我经常希望能够向析构函数传递一个“环境”参数,但是我无法这样做,只能将一个“环境”指针成员添加到这些类的每个实例中,这浪费了大量内存。 - Mooing Duck
@MooingDuck 我也有同样的问题。编译器强制要求(用户)调用带参数的构造函数可以避免我遇到难以调试的错误。 - Adam

9
不,简单来说是不行的。这会使自动资源管理变得非常麻烦,因为您需要担心析构函数所需的参数以及从哪里获取它们。那么在异常情况下呢?编译器怎么知道该传递什么给您的析构函数呢?

2

不需要。你几乎从来没有直接联系他们,所以有什么用呢。

析构函数只需要销毁对象,没有其他作用。


1
一个包含结构体的联合体,如果需要调用正确的结构体析构函数,那么是否需要一个析构函数呢?删除默认构造函数并强制联合体所有者调用正确的析构函数会很方便。(考虑至少有一个结构体是非平凡的/包含unique_ptr)。 - user2864740

0

我认为有时候带参数的析构函数是可用的。

考虑pmr。当我们使用pmr容器,例如std::pmr::vector<std::pmr::string>时,在每个std::pmr::string中,它将存储一个指向pmr分配器的指针,但是该指针存储在std::pmr::vector中,我们不必在每个std::pmr::string中存储它。如果我们可以将指针传递给std::pmr::string的析构函数,我们就不必存储它了。

目前,我们没有任何方法可以将参数传递给析构函数。顺便说一下,我们可以使用偏移量来获取参数(这种方式很丑陋,不能在实践中使用,如果有更好的方法,请告诉我)。这里是一个示例


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