Bagaimanakah anda boleh memulakan ahli statik dengan pasti dalam kelas C templat menggunakan struktur pembantu bersarang?

Barbara Streisand
Lepaskan: 2024-10-30 05:43:02
asal
967 orang telah melayarinya

 How can you reliably initialize static members in templated C   classes using nested helper structs?

Permulaan Ahli Statik dalam Kelas Templat dan Pembantu Pemula

Dalam C , ahli statik boleh dimulakan menggunakan struct helper bersarang. Walaupun pendekatan ini berfungsi dengan baik untuk kelas bukan templat, ia boleh menimbulkan cabaran dalam kelas dengan parameter templat.

Pernyataan Masalah

Pertimbangkan contoh berikut, di mana pembantu permulaan ahli statik digunakan dalam kelas templat:

<code class="cpp">struct A
{
    struct InitHelper
    {
        InitHelper() { A::mA = "Hello, I'm A."; }
    };
    static std::string mA;
    static InitHelper mInit;

    static const std::string& getA() { return mA; }
};

template<class T>
struct B
{
    struct InitHelper
    {
        InitHelper() { B<T>::mB = "Hello, I'm B."; } // [3]
    };
    static std::string mB;
    static InitHelper mInit; // [4]

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper() { return mInit; }
};</code>
Salin selepas log masuk

Dalam senario ini, pemerhatian berikut dibuat:

  • Dengan [1] dan [2] diulas keluar, output adalah seperti yang dijangkakan: "A = Helo, saya A.".
  • Dengan [1] tidak diulas, output ialah "A = Hello, saya A.nB = " dan bukannya "Hello, saya B. ".
  • Dengan kedua-dua [1] dan [2] tidak diulas, output adalah seperti yang dijangkakan: "A = Hello, saya A.nB = Hello, saya B.".
  • Dengan [1] mengulas keluar dan [2] tidak mengulas, atur cara segfault pada [3].

Penjelasan

Tingkah laku yang tidak dijangka berpunca daripada gelagat permulaan ahli statik dalam kelas templat. Menurut piawaian ISO/IEC C 2003 (14.7.1), pemulaan ahli data statik berlaku hanya jika ahli data statik itu sendiri digunakan dalam cara yang memerlukan takrifannya wujud.

  • Dalam kes A, ahli data statik mA dirujuk secara eksplisit dalam utama, jadi permulaannya berlaku sebelum fungsi utama dilaksanakan.
  • Dalam kes B, mengakses B::getB() rujukan B::mB, mencetuskan permulaannya. Walau bagaimanapun, mengakses B::getHelper() tidak langsung menggunakan B::mInit, hanya mengembalikan alias kepada pembantu pemula.

Penyelesaian

Kepada elakkan pergantungan pada permulaan tersirat dan memastikan susunan permulaan yang konsisten, adalah disyorkan untuk mengkhususkan ahli data statik secara eksplisit dalam templat kelas. Dalam kes ini:

<code class="cpp">template<>
std::string B<int>::mB = "Hello, I'm B (int specialization).";</code>
Salin selepas log masuk

Dengan mengkhususkan ahli data statik secara eksplisit untuk setiap instantiasi kelas templat, pemulaan dicetuskan secara eksplisit dan gelagat yang diingini dicapai tanpa perlu mengakses pembantu pemula.

Atas ialah kandungan terperinci Bagaimanakah anda boleh memulakan ahli statik dengan pasti dalam kelas C templat menggunakan struktur pembantu bersarang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!