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 集合体。p. #3) によれば、「イニシャライザ リストが指定イニシャライザ リストの場合、集合体はクラス型でなければならず、各指定子の識別子はクラスの直接の非静的データ メンバーを指定する必要があります。
これは、指定された初期化子は、クラス内で直接宣言されたデータ メンバーのみを初期化でき、初期化できないことを意味します。基本クラスから継承されたメンバー。
したがって、指定された初期化子を使用して Employee を e1 として初期化することは正しくありません。代わりに、通常のリスト初期化を使用する必要があります:
<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このアプローチは、Employee クラスに通常のイニシャライザを使用しながら、指定されたイニシャライザで Person 基本クラスを正しく初期化します。
以上が指定イニシャライザと継承: 指定イニシャライザを使用して従業員を初期化できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。