Heim  >  Artikel  >  Backend-Entwicklung  >  Wie können Sie statische Mitglieder in C-Klassen mit Vorlagen mithilfe verschachtelter Hilfsstrukturen zuverlässig initialisieren?

Wie können Sie statische Mitglieder in C-Klassen mit Vorlagen mithilfe verschachtelter Hilfsstrukturen zuverlässig initialisieren?

Barbara Streisand
Barbara StreisandOriginal
2024-10-30 05:43:02953Durchsuche

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

Statische Member-Initialisierung in Vorlagenklassen und Initialisierungshelfern

In C können statische Member mithilfe verschachtelter Hilfsstrukturen initialisiert werden. Während dieser Ansatz für Klassen ohne Vorlagen gut funktioniert, kann er in Klassen mit Vorlagenparametern zu Herausforderungen führen.

Problemstellung

Betrachten Sie das folgende Beispiel, in dem ein statischer Member-Initialisierungshelfer in a verwendet wird Vorlageklasse:

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

In diesem Szenario werden die folgenden Beobachtungen gemacht:

  • Wenn [1] und [2] auskommentiert sind, ist die Ausgabe wie erwartet: „A = Hallo, ich bin A..
  • Wenn [1] unkommentiert ist, lautet die Ausgabe „A = Hallo, ich bin A.nB =“ anstelle des erwarteten „Hallo, ich bin B.“ ".
  • Wenn sowohl [1] als auch [2] unkommentiert sind, ist die Ausgabe wie erwartet: „A = Hallo, ich bin A.nB = Hallo, ich bin B.“
  • Wenn [1] auskommentiert und [2] unkommentiert ist, weist das Programm einen Segmentierungsfehler bei [3] auf.

Erklärung

Das unerwartete Verhalten ist auf das Verhalten der statischen Elementinitialisierung in zurückzuführen Klassen mit Vorlagen. Gemäß dem ISO/IEC C 2003-Standard (14.7.1) erfolgt die Initialisierung eines statischen Datenelements nur, wenn das statische Datenelement selbst auf eine Weise verwendet wird, die das Vorhandensein seiner Definition erfordert.

  • Im Fall von A wird das statische Datenelement mA explizit in main referenziert, sodass seine Initialisierung erfolgt, bevor die Hauptfunktion ausgeführt wird.
  • Im Fall von B erfolgt der Zugriff auf B::getB() verweist auf B::mB und löst dessen Initialisierung aus. Beim Zugriff auf B::getHelper() wird B::mInit jedoch nicht direkt verwendet, sondern nur ein Alias ​​an den Initialisierungshelfer zurückgegeben.

Lösung

An Vermeiden Sie die Abhängigkeit von der impliziten Initialisierung und stellen Sie eine konsistente Initialisierungsreihenfolge sicher. Es wird empfohlen, das statische Datenelement explizit in der Klassenvorlage zu spezialisieren. In diesem Fall:

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

Durch die explizite Spezialisierung des statischen Datenelements für jede Instanziierung der Vorlagenklasse wird die Initialisierung explizit ausgelöst und das gewünschte Verhalten erreicht, ohne dass auf den Initialisierungshelfer zurückgegriffen werden muss.

Das obige ist der detaillierte Inhalt vonWie können Sie statische Mitglieder in C-Klassen mit Vorlagen mithilfe verschachtelter Hilfsstrukturen zuverlässig initialisieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn