Heim  >  Artikel  >  Backend-Entwicklung  >  Designierte Initialisierer und Vererbung: Warum kann ich einen Mitarbeiter nicht mit einem designierten Initialisierer initialisieren?

Designierte Initialisierer und Vererbung: Warum kann ich einen Mitarbeiter nicht mit einem designierten Initialisierer initialisieren?

DDD
DDDOriginal
2024-11-02 08:06:02175Durchsuche

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

Designierte Initialisierer in C 20: Ein Rätsel mit Mitarbeiterinitialisierung

Die designierten Initialisierer von C 20 ermöglichen eine präzise Elementinitialisierung für Klassen, die als Aggregate betrachtet werden. Es stellt sich jedoch die Frage, wenn eine Klasse von einer aggregierten Basisklasse erbt, wie durch den bereitgestellten Code veranschaulicht:

<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>

In diesem Fall gelten sowohl Person als auch Employee als Aggregate, Employee kann jedoch nicht mit der angegebenen Initialisierung initialisiert werden Initialisierer. Die Erklärung liegt in der Regelung des C 20-Standards zu designierten Initialisierern:

Gemäß dem C 20-Standard (9.3.1 Aggregates. S. 3): „Wenn die Initialisiererliste eine designierte Initialisiererliste ist, Das Aggregat muss vom Klassentyp sein, der Bezeichner in jedem Bezeichner muss ein direktes, nicht statisches Datenmitglied der Klasse benennen kann nur direkt in der Klasse deklarierte Datenelemente initialisieren, keine von einer Basisklasse geerbten Elemente.

Daher ist die Initialisierung von Employee mit den angegebenen Initialisierern wie e1 falsch. Stattdessen muss die übliche Listeninitialisierung verwendet werden:

Alternativ kann man, da Employee direkt von Person erbt, einen verschachtelten designierten Initialisierer für die Basisklasse verwenden:
<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 };</code>

This Der Ansatz initialisiert die Basisklasse „Person“ korrekt mit festgelegten Initialisierern und verwendet gleichzeitig einen regulären Initialisierer für die Klasse „Employee“.
<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };</code>

Das obige ist der detaillierte Inhalt vonDesignierte Initialisierer und Vererbung: Warum kann ich einen Mitarbeiter nicht mit einem designierten Initialisierer initialisieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn