首頁 >後端開發 >C++ >指定初始化程序和繼承:為什麼我不能使用指定初始化程序初始化員工?

指定初始化程序和繼承:為什麼我不能使用指定初始化程序初始化員工?

DDD
DDD原創
2024-11-02 08:06:02229瀏覽

  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 是不正確的。相反,必須使用通常的列表初始化:

或者,由於Employee 直接繼承自Person,因此可以為基類使用嵌套的指定初始化器:
<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 };</code>

This方法使用指定的初始化器正確初始化Person 基底類,同時為Employee 類別使用常規初始化器。
<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };</code>

以上是指定初始化程序和繼承:為什麼我不能使用指定初始化程序初始化員工?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn