默认析构函数的用途是什么?

What are defaulted destructors used for?

本文关键字:是什么 析构函数 默认      更新时间:2023-10-16

我可以理解默认构造函数,因为用户定义的构造函数将禁用编译器生成的构造函数,使对象不可复制等。

在析构函数的情况下,除了更改访问类别之外,考虑到没有用户定义的成员函数可以禁用默认析构函数(无论如何都不能重载析构函数),定义默认析构函数有什么用?

// Which version should I choose ? 
struct Example 
{
    //1. ~Example() = default; 
    //2. ~Example() {}
    //3. 
}; 

即使在虚析构函数的情况下,默认它们也不会使它们变得微不足道,所以这样做有什么好处呢?

省略普通析构函数的例外与派生的类的析构函数有关,而与基类无关。因此,virtual ~Foo() = default;是一个有用的构造,可以保留默认析构函数,但可以虚拟化它。

一种用法是使析构函数protectedprivate,同时可能保持类的不重要:只需在所需的访问说明符之后列出它。

另外:在编写类时,一些程序员喜欢对类的函数进行排序:例如,构造函数,然后是析构函数,然后是非const"变异"成员,然后是const"访问器"成员,然后是static函数。通过显式地= default析构函数,您可以按照预期的顺序列出它,并且查找它的读者知道不可能有另一个放错位置的版本。在大班中,这可能有一定的记录/安全价值。

它还为您提供了一些具体的东西来添加注释,这可以帮助一些文档工具意识到注释与销毁有关。

基本上是关于传达意图,但相当多余。

但是如果你使用std::unique_ptr作为类的成员,你需要在header中声明析构函数(但只声明)。然后你可以让它在源文件中使用默认实现,如下所示:

MyClass:~MyClass() = default;

考虑到你的选择,我会用第一个或第三个

正如Nikos Athanasiou在评论中提到的那样,默认构造函数使类型易于破坏,而用户定义的构造函数则不然。下面的代码示例将展示它:

#include <iostream>
#include <type_traits>
struct A { ~A() = default; };
struct B { ~B() {} };
struct C { ~C() noexcept {} };
int main() {
  std::cout
    << std::is_trivially_destructible<A>::value
    << std::is_trivially_destructible<B>::value
    << std::is_trivially_destructible<C>::value
    << std::endl;
  return 0;
}

显示
100

对于虚析构函数,与非虚析构函数的一致性和Quentin的回答是恰当的理由。我个人的建议是,你应该尽可能使用默认值,因为这是一种坚持最规范行为的方法。