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 Standard의 규정에 있습니다.
C 20 Standard(9.3.1 Aggregates. p. #3)에 따르면, "초기화 목록이 지정 이니셜라이저 목록인 경우, 집합체는 클래스 유형이어야 하며, 각 지정자의 식별자는 클래스의 직접적인 비정적 데이터 멤버의 이름을 지정해야 합니다."
이는 지정된 초기화 프로그램이 클래스에서 직접 선언된 데이터 멤버만 초기화할 수 있음을 의미합니다. 멤버는 기본 클래스에서 상속됩니다.
따라서 지정된 초기화 프로그램을 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>
이것은 이 접근 방식은 Employee 클래스에 일반 초기화를 사용하면서 지정된 초기화로 Person 기본 클래스를 올바르게 초기화합니다.
위 내용은 지정 이니셜라이저 및 상속: 지정 이니셜라이저를 사용하여 직원을 초기화할 수 없는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!