【问题标题】:Rule of zero - default constructor not generated零规则 - 未生成默认构造函数
【发布时间】:2021-08-08 14:14:03
【问题描述】:

我在读这个:https://en.cppreference.com/w/cpp/language/rule_of_three

我的理解是,如果你想拥有一个带有虚析构函数的基类,你需要定义所有 5 个特殊函数(从 0 部分的规则中提取):

class base_of_five_defaults
{
 public:
    base_of_five_defaults(const base_of_five_defaults&) = default;
    base_of_five_defaults(base_of_five_defaults&&) = default;
    base_of_five_defaults& operator=(const base_of_five_defaults&) = default;
    base_of_five_defaults& operator=(base_of_five_defaults&&) = default;
    virtual ~base_of_five_defaults() = default;
};

但是,当我尝试创建该类时,我收到错误消息,提示“未创建默认 c'tor”:

    base_of_five_defaults b; // Error

然后,如果我生成默认值就可以了:

base_of_five_defaults() = default;

但我根本不明白这是需要的......所以我很困惑为什么它不存在。我认为编译器不生成默认构造函数的唯一原因是如果您指定了非默认构造函数...

如果您确实需要指定默认 c'tor,那么示例中的类是不可构造的 - 这看起来很奇怪。

这是我的完整示例的链接:https://godbolt.org/z/qPvjd6r51


来自https://en.cppreference.com/w/cpp/language/default_constructor

隐式声明的默认构造函数

如果没有用户声明 为类类型(结构、类、 或联合),编译器将始终将默认构造函数声明为 其类的内联公共成员。

我猜这意味着如果声明了base_of_five_defaults(const base_of_five_defaults&) = default;,那么即使它是“默认”,它也被认为是用户声明的?

【问题讨论】:

  • 它的意思是用作基类(尽管这不会改变无法构造它的事实)
  • @largest_prime_is_463035818 但基类 can 是可构造的,除非它特别抽象......但我明白你的意思 - 我确实觉得这个例子有点奇怪:)跨度>
  • 该示例与“C.21:如果您定义或 =delete 任何复制、移动或析构函数,则定义或 =delete 它们全部” 要么我遗漏了什么,要么他们只是错过了将其包含在示例中。其实我不知道如何接受base_of_five_defaults,它是作为一个真正的实用程序还是仅仅为了证明这一点?我倾向于后者
  • 因为你定义了至少一个显式的ctor,所以隐式的默认ctor被移除了?
  • 哦,等一下。我误读了C21。它实际上没有提到构造函数。一定有我想念的东西;)

标签: c++ default-constructor rule-of-zero


【解决方案1】:

我猜这意味着如果声明了base_of_five_defaults(const base_of_five_defaults&) = default;,那么即使它是“默认”的,它也被认为是用户声明的?

是的base_of_five_defaults(base_of_five_defaults&&) = default; 声明 a1defaulted user-declared 构造函数。

= default 使编译器生成这样一个构造函数的定义,但它已经被用户声明了。

C++ 标准没有提供 user-declared 的明确定义,因此英语中的意思是“由用户声明”。

这就是[class.default.ctor]/1 咬你的地方:

[class.default.ctor]/1

类 X 的默认构造函数是类 X 的构造函数,其中每个不是函数参数包的参数都有一个默认参数(包括没有参数的构造函数的情况)。
如果类 X 没有用户声明的构造函数,没有参数的非显式构造函数被隐式声明为默认值 ([dcl.fct.def])。
隐式声明的默认构造函数是其类的内联公共成员。


1)不管是带参数还是不带参数的构造函数,见[class.default.ctor]/1的写法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 2013-01-23
    • 2019-08-09
    • 2015-10-09
    • 2016-10-16
    相关资源
    最近更新 更多