Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah anda boleh memulakan ahli statik dengan pasti dalam kelas C templat menggunakan struktur pembantu bersarang?

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

Barbara Streisand
Barbara Streisandasal
2024-10-30 05:43:02953semak imbas

 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>

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>

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!

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