首页  >  文章  >  后端开发  >  指定初始化程序和继承:为什么我不能使用指定初始化程序初始化员工?

指定初始化程序和继承:为什么我不能使用指定初始化程序初始化员工?

DDD
DDD原创
2024-11-02 08:06:02105浏览

  Designated Initializers and Inheritance: Why Can't I Initialize an Employee with a Designated Initializer?

C 20 中的指定初始化器:员工初始化之谜

C 20 的指定初始化器允许对被视为聚合的类进行精确的成员初始化。然而,当一个类继承自聚合基类时,就会出现问题,如提供的代码所示:

<code class="cpp">#include <iostream>

constexpr unsigned DEFAULT_SALARY {10000};

struct Person
{
    std::string name{};
    std::string surname{};
    unsigned age{};
};

struct Employee : Person
{
    unsigned salary{DEFAULT_SALARY};
};

int main()
{
    std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed
    std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed

    Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok
    Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ?

    // For e2 compiler prints a warning "missing initializer for member 'Employee::<anonymous>' [-Wmissing-field-initializers]"
    Employee e2 {.salary{55000}};
}</code>

在这种情况下,Person 和 Employee 都被视为聚合,但 Employee 不能用指定的值进行初始化初始化器。解释在于 C 20 标准关于指定初始化器的规定:

根据 C 20 标准(9.3.1 聚合。第 #3 页),“如果初始化器列表是指定初始化器列表,聚合应为类类型,每个指示符中的标识符应命名该类的直接非静态数据成员。”

这意味着指定的初始化器只能初始化直接在类中声明的数据成员,而不能初始化从基类继承的成员。

因此,使用指定的初始值设定项作为 e1 来初始化 Employee 是不正确的。相反,必须使用通常的列表初始化:

<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 };</code>

或者,由于 Employee 直接继承自 Person,因此可以为基类使用嵌套的指定初始化器:

<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };</code>

This方法使用指定的初始化器正确初始化 Person 基类,同时为 Employee 类使用常规初始化器。

以上是指定初始化程序和继承:为什么我不能使用指定初始化程序初始化员工?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn