Maison > développement back-end > C++ > le corps du texte

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

DDD
Libérer: 2024-11-02 08:06:02
original
174 Les gens l'ont consulté

  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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal