Maison  >  Article  >  développement back-end  >  Initialiseurs désignés et héritage : pourquoi ne puis-je pas initialiser un employé avec un initialiseur désigné ?

Initialiseurs désignés et héritage : pourquoi ne puis-je pas initialiser un employé avec un initialiseur désigné ?

DDD
DDDoriginal
2024-11-02 08:06:02184parcourir

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

Initialiseurs désignés dans C 20 : une énigme avec l'initialisation des employés

Les initialiseurs désignés du C 20 permettent une initialisation précise des membres pour les classes considérées comme des agrégats. Cependant, la question se pose lorsqu'une classe hérite d'une classe de base agrégée, comme l'illustre le code fourni :

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

Dans ce cas, Person et Employee sont tous deux considérés comme des agrégats, mais Employee ne peut pas être initialisé avec l'attribut désigné. initialiseurs. L'explication réside dans la réglementation de la norme C 20 concernant les initialiseurs désignés :

Selon la norme C 20 (9.3.1 Agrégats. p. #3), "Si la liste d'initialiseurs est une liste d'initialiseurs désignés, l'agrégat doit être de type classe, l'identifiant dans chaque désignateur doit nommer une donnée membre directe non statique de la classe. "

Cela signifie que les initialiseurs désignés ne peuvent initialiser que les données membres directement déclarées dans la classe, et non membres hérités d'une classe de base.

Par conséquent, l'initialisation de Employee à l'aide des initialiseurs désignés comme e1 est incorrecte. Au lieu de cela, l'initialisation de liste habituelle doit être utilisée :

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

Alternativement, puisque Employee hérite directement de Person, on peut utiliser un initialiseur désigné imbriqué pour la classe de base :

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

Ceci Cette approche initialise correctement la classe de base Person avec des initialiseurs désignés tout en employant un initialiseur régulier pour la classe Employee.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn