始终声明默认构造函数的优缺点是什么?

What are the pros and cons of always declaring defaulted constructors?

本文关键字:优缺点 是什么 构造函数 声明 默认      更新时间:2023-10-16

为每个非用户定义的构造函数声明始终默认构造函数的利弊是什么?

考虑一个具有用户定义构造器的类,该类不需要其他用户定义的构造函数,它将是:

class Foo
{
public:
Foo() { // user-defined declaration }
Foo(const Foo&) = default;
Foo(Foo&&) noexcept = default;
~Foo() = default;
Foo& operator=(const Foo&) = default;
Foo& operator=(Foo&&) = default;
}

这样做还有其他实际的优点/缺点吗?

我头顶的几个缺点:

  1. 您可以忘记特殊功能。您显示的示例未定义复制/移动赋值运算符。
  2. 在标头中将析构函数声明为默认值将使您无法在类的std::unique_ptr成员中使用前向声明的类。您可以通过包含类定义来缓解此问题(导致非平凡项目的(重新)构建时间最终总体增加,尤其是在未向前声明的类经常更改时)。可以通过将= default移动到源文件中的定义来缓解此问题。
  3. (主观)它在视觉上重载了类定义:每个有能力C++开发人员都知道这些通常是自动生成的,因此尽管它们需要时间来阅读和理解,但它们不提供额外的信息。请注意,我只是在谈论"所有默认"情况,因此不会删除任何特殊功能或类似功能。
  4. 添加仅移动数据成员还需要删除 =default 复制构造函数和赋值运算符。你是否希望这样做是必要的部分是风格问题,但这确实会导致更多涉及的代码更改,尤其是在更一般的意义上重构此类类时。
  5. 如果将任何其他特殊的编译器生成的函数添加到更高版本的C++中,则会自动错过它们,否则您已经隐式定义了它们。

可能还有更多,在微妙程度的上升超过这些。

没有优势。它只是向代码的读者证明您不知道C++编译器的工作原理。如果将此作为策略强制执行,则也容易受到未来C++标准更改的影响。

使用异常

virtual ~Foo() = default;

在基类中,我们引入了可以帮助内存管理的多态性。

另一类例外是您可能希望更改defaultable 函数的访问说明符的情况:

protected:
Foo foo() = default;

如果您只想通过继承使用类,但不想使其成为多态类型,我在这里给出的显式示例可能很有用。