【问题标题】:Should the user-defined empty destructor never be used?永远不要使用用户定义的空析构函数吗?
【发布时间】:2021-07-12 23:15:59
【问题描述】:
struct A1
{
    ~A1() {} // A1 is not trivially destructible
};

struct A2
{
    ~A2() = default; // A2 is trivially destructible
};

A2A1 更好,因为 A2 可以轻易破坏,而 A1 则不行。

我想也许我们可以放心地说:

1.永远不要使用用户定义的空析构函数。

2.任何用户定义的空析构函数都应替换为默认析构函数。

我说的对吗?

【问题讨论】:

  • 我与 2 争论“任何用户定义的空析构函数都应该删除”。除非您出于自我记录的目的需要将其保留为默认值。
  • 我同意,请参阅:isocpp.github.io/CppCoreGuidelines/…
  • @Yksisarvinen 核心准则说:“如果默认析构函数足够,请使用它。”所以我会说:是的,替换。
  • t@Roxxorfreak 这里的“默认”似乎意味着“隐式”。链接规则的第一句话说:“这个类需要析构函数吗?”是一个令人惊讶的有见地的设计问题。对于大多数类来说,答案是“否”,要么是因为该类没有资源,要么是因为销毁是由零规则处理的。零规则说:If you can avoid defining default operations, do

标签: c++ c++11 destructor semantics idioms


【解决方案1】:

您可以在示例中看到这样一个空析构函数的用例。您可以使用它来强制平凡的类型变得不平凡。这是一个极不可能的用例。但我完全没有信心说它永远没有用。

不过,你离目标并不远。在 C++ 编程的十年中,我每天都看到很多空的析构函数,但没有一个是不能用 =default 替换或完全省略的。

不过,我还是会警惕机械替代品。所以:

  1. 几乎不应该使用用户定义的空析构函数。

  2. 几乎每个用户定义的空析构函数都应该完全省略(首选选项)或替换为默认值。

【讨论】:

    【解决方案2】:

    在头文件中:

    struct some_secret_type;
    struct some_public_type {
      some_public_type();
      ~some_public_type();
    private:
      std::unique_ptr<some_secret_type> pImpl;
    };
    

    然后,在cpp文件中:

    #include <some_secret_type.h>
    
    some_public_type::~some_public_type() = default;
    some_public_type::~some_public_type() {};
    

    在这里,我明确声明了一个最终为空或默认的析构函数。

    这里=default;{}的效果在cpp文件中是一样的。

    在头文件中,拥有{}=default 将要求包括它在内的每个人都知道some_secret_type 的样子。

    在更一般的情况下,如果类型被简单地销毁,则标头中的 {}=default 可以更改。在 cpp/header 拆分中,它们没有。

    标题中{} 的优点是可以防止类型变得琐碎(假设稍后您知道要使其变得非琐碎,并且您不希望在这样做时发生其他行为更改它)。

    在 cpp 文件的情况下,{} 保存了几个字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 2017-07-21
      • 2018-07-22
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多