Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pemula dan Warisan Ditetapkan: Mengapakah Saya Tidak Boleh Memulakan Pekerja dengan Pemula Ditetapkan?

Pemula dan Warisan Ditetapkan: Mengapakah Saya Tidak Boleh Memulakan Pekerja dengan Pemula Ditetapkan?

DDD
DDDasal
2024-11-02 08:06:02105semak imbas

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

Pemula Ditetapkan dalam C 20: Enigma dengan Permulaan Pekerja

Pemula yang ditetapkan C 20 membenarkan pemulaan ahli yang tepat untuk kelas yang dianggap sebagai agregat. Walau bagaimanapun, persoalan timbul apabila kelas mewarisi daripada kelas asas agregat, seperti yang ditunjukkan oleh kod yang disediakan:

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

Dalam kes ini, kedua-dua Orang dan Pekerja dianggap sebagai agregat, namun Pekerja tidak boleh dimulakan dengan ditetapkan pemula. Penjelasan terletak pada peraturan C 20 Standard berkenaan pemula yang ditetapkan:

Menurut Piawaian C 20 (9.3.1 Agregat. ms #3), "Jika senarai pemula ialah senarai-pemula yang ditetapkan, agregat hendaklah daripada jenis kelas, pengecam dalam setiap penentu hendaklah menamakan ahli data bukan statik langsung bagi kelas itu."

Ini bermakna pemula yang ditetapkan hanya boleh memulakan ahli data yang diisytiharkan secara langsung dalam kelas, bukan ahli yang diwarisi daripada kelas asas.

Oleh itu, memulakan Pekerja menggunakan pemula yang ditetapkan sebagai e1 adalah tidak betul. Sebaliknya, permulaan senarai biasa mesti digunakan:

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

Sebagai alternatif, memandangkan Pekerja mewarisi terus daripada Orang, seseorang boleh menggunakan pemula yang ditetapkan bersarang untuk kelas asas:

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

Ini pendekatan dengan betul memulakan kelas asas Orang dengan pemula yang ditetapkan sambil menggunakan pemula biasa untuk kelas Pekerja.

Atas ialah kandungan terperinci Pemula dan Warisan Ditetapkan: Mengapakah Saya Tidak Boleh Memulakan Pekerja dengan Pemula Ditetapkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn