始终声明默认构造函数的优缺点是什么?
What are the pros and cons of always declaring defaulted constructors?
为每个非用户定义的构造函数声明始终默认的构造函数的优缺点是什么?
考虑一个 class 和一个不需要其他用户定义构造函数的用户定义构造函数,它将是:
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;
}
还有其他实际的 advantages/disadvantages 这样做?
我头顶的几个缺点:
- 你可以忘记特殊功能。您显示的示例未定义 copy/move 赋值运算符。
- 在 header 中将析构函数声明为默认值将使您无法使用前向声明的 classes,例如class 的
std::unique_ptr
成员。您可以通过包含 class 定义来缓解这种情况(导致 non-trivial 项目的(重新)构建时间最终总体增加,尤其是当未向前声明的 class 经常更改时)。您可以通过将 = default
移动到源文件中的定义来缓解这种情况。
- (主观)它在视觉上重载了 class 定义:每个有能力的 C++ 开发人员都知道这些通常是自动生成的,因此尽管需要时间阅读和理解它们,但它们不提供额外信息。请注意,我只是在谈论 "everything default" 案例,因此没有删除任何特殊功能或类似功能。
- 添加 move-only 数据成员还需要删除 =default 复制构造函数和赋值运算符。您是否需要这样做在一定程度上是风格问题,但这确实会导致更多的代码更改,尤其是在更一般意义上重构 class 这样的代码时。
- 如果任何其他特殊 compiler-generated 函数被添加到更高版本的 C++ 中,您会自动错过它们,否则您已经隐式定义了它们。
可能还有更多,在这些之外的微妙程度不断提高。
没有优势。它只是向您的代码的 reader 证明您不知道 C++ 编译器是如何工作的。如果您将此作为一项政策强制执行,您也很容易受到未来 C++ 标准更改的影响。
异常正在使用
virtual ~Foo() = default;
在基础class中,我们引入了有助于内存管理的多态性。
另一个 class 例外情况是您可能想要更改 default
可用函数的访问说明符:
protected:
Foo foo() = default;
如果您仅想通过继承使用class,但又不想使其成为多态类型,那么我在这里给出的明确示例可能会有用.
为每个非用户定义的构造函数声明始终默认的构造函数的优缺点是什么?
考虑一个 class 和一个不需要其他用户定义构造函数的用户定义构造函数,它将是:
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;
}
还有其他实际的 advantages/disadvantages 这样做?
我头顶的几个缺点:
- 你可以忘记特殊功能。您显示的示例未定义 copy/move 赋值运算符。
- 在 header 中将析构函数声明为默认值将使您无法使用前向声明的 classes,例如class 的
std::unique_ptr
成员。您可以通过包含 class 定义来缓解这种情况(导致 non-trivial 项目的(重新)构建时间最终总体增加,尤其是当未向前声明的 class 经常更改时)。您可以通过将= default
移动到源文件中的定义来缓解这种情况。 - (主观)它在视觉上重载了 class 定义:每个有能力的 C++ 开发人员都知道这些通常是自动生成的,因此尽管需要时间阅读和理解它们,但它们不提供额外信息。请注意,我只是在谈论 "everything default" 案例,因此没有删除任何特殊功能或类似功能。
- 添加 move-only 数据成员还需要删除 =default 复制构造函数和赋值运算符。您是否需要这样做在一定程度上是风格问题,但这确实会导致更多的代码更改,尤其是在更一般意义上重构 class 这样的代码时。
- 如果任何其他特殊 compiler-generated 函数被添加到更高版本的 C++ 中,您会自动错过它们,否则您已经隐式定义了它们。
可能还有更多,在这些之外的微妙程度不断提高。
没有优势。它只是向您的代码的 reader 证明您不知道 C++ 编译器是如何工作的。如果您将此作为一项政策强制执行,您也很容易受到未来 C++ 标准更改的影响。
异常正在使用
virtual ~Foo() = default;
在基础class中,我们引入了有助于内存管理的多态性。
另一个 class 例外情况是您可能想要更改 default
可用函数的访问说明符:
protected:
Foo foo() = default;
如果您仅想通过继承使用class,但又不想使其成为多态类型,那么我在这里给出的明确示例可能会有用.