如果我没有为C ++类提供显式析构函数,因为我确信编译器提供的默认析构函数是我所有类的需求,那很好吗?或者这被认为是不好的做法?
答案 0 :(得分:6)
仅在两种情况下需要显式析构函数:
何时需要运行时多态性。在这种情况下,基类析构函数需要为virtual
- 此要求强制您显式定义析构函数(即使它是空的!)。但是,派生类可能有也可能没有显式析构函数,具体取决于它们是否管理资源(这是第二个要点)。
当您的类是资源管理类时 - 即它实现RAII idiom。在这种情况下,可能还需要实现复制语义和移动语义。
在所有其他情况下,不需要显式定义的析构函数。 : - )
答案 1 :(得分:4)
提供显式析构函数的主要优点是您可以轻松地将断点放入其中以进行调试。有些人喜欢这样,并且更愿意为每个类提供一个明确的析构函数。
但是,如果该类非常简单,显然默认构造函数就足够了,那么省略它就完全没问题了。另请注意,添加析构函数确实有其缺点:除了代码中的额外噪声之外,添加析构函数可能会阻止您的类成为POD。所以你仍然应该避免在你的代码中盲目地传播琐碎的析构函数。
我认为忽略空的非虚拟析构函数有害的唯一情况是,当不明显为什么破坏是微不足道的时候(例如,如果rule-of-three / rule-of-five建议你需要一个)。在这种情况下,我仍然会提供一个显式的空析构函数,在正文中注释为什么不做任何事情都是安全的。但这更像是个人偏好而非固定规则。
答案 2 :(得分:1)
是的,这完全没问题。您自己提供析构函数主要有三个理由:
案例1和案例2是相互排斥的,在案例3中,SRP要求该类的目的仅仅是对所拥有资源的管理,因此它不应该是基类,使所有三种情况互相排斥。这就是为什么基类析构函数和几乎任何“普通类”析构函数都应该默认的原因(参见this article about The Rule of Zero)。
当然,有许多极端情况并不完全符合该方案,并且在某些情况下需要使用析构函数。但一般来说,如果您确定默认的析构函数可以完成所需的操作,则无需自行定义。
答案 3 :(得分:0)
这取决于你的构造函数在做什么。 C ++不提供垃圾收集,因此如果构造函数正在创建新对象,最好在析构函数中删除它们。 无论如何都要释放用于类成员的内存,因此如果你没有在构造函数中使用“new”而不以任何其他方式分配内存,则析构函数不是必需的。
答案 4 :(得分:0)
如果适用,您通常应提供以下内容定义:
析构函数是virtual
,您的类不提供任何脱机虚拟定义(请记住,带有虚拟析构函数的基础会使您的析构函数virtual
)。许多实现在转换中发出vtable和RTTI信息,其中包含第一个异常虚拟成员函数的定义。如果许多翻译都可以看到这种类型,这可能会导致大量克隆信息。
或者成员的破坏是'重量级'
这两个可以减少二进制大小和构建时间的大部分。
您也可以将其定义为正确的,以便正确delete
一个PIMPL成员(基于哪些标题在智能指针的位置和机制中可见)。