Heim > Backend-Entwicklung > C++ > Warum kann „B::getB()' „mB' in Vorlagenklassen mit statischen Mitgliedern nicht initialisieren?

Warum kann „B::getB()' „mB' in Vorlagenklassen mit statischen Mitgliedern nicht initialisieren?

Linda Hamilton
Freigeben: 2024-10-31 05:59:02
Original
520 Leute haben es durchsucht

 Why Does `B::getB()` Fail to Initialize `mB` in Templated Classes with Static Members?

Statische Member-Initialisierung in Vorlagen: Ein tieferer Einblick

In C funktioniert die statische Member-Initialisierung für verschachtelte Hilfsstrukturen normalerweise ohne Probleme für nicht auf Vorlagen basierende Klassen. Wenn die umschließende Klasse jedoch eine Vorlage ist, entsteht eine potenzielle Eigenart, wenn im Hauptcode nicht auf das Hilfsobjekt zugegriffen wird.

Das Problem mit Vorlagenklassen

Betrachten Sie das folgende vereinfachte Beispiel:

<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.";
        }
    };
    static std::string mB;
    static InitHelper mInit;

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper(){ return mInit; }
};</code>
Nach dem Login kopieren

Hier initialisiert der verschachtelte InitHelper das statische Mitglied mA für A und mB für B.

Das Problem tritt auf, wenn wir versuchen, die Mitglieder in einer Vorlagenklasse B zu initialisieren. Mithilfe der getB-Methode , wie unten gezeigt, löst nicht die Initialisierung von mB aus:

<code class="cpp">std::cout << "B = " << B<int>::getB() << std::endl;
Nach dem Login kopieren

Dies geschieht, weil gemäß dem ISO/IEC C 2003-Standard (14.7.1) die Initialisierung nur eines statischen Datenelements erfolgt wenn das Element selbst auf eine Weise verwendet wird, die seine Definition erfordert. Da mB in diesem Fall nur in der getB()-Methode der Vorlagenklasse referenziert wird, instanziiert der Compiler seine Definition nicht implizit.

Implizite Instanziierung und explizite Spezialisierung

Zum Verständnis des Compilers Verhalten ist es wichtig, das Konzept der impliziten Instanziierung zu klären. Für statische Datenelemente in Vorlagen instanziiert eine implizite Instanziierung die Deklarationen, nicht jedoch die Definitionen. Die eigentliche Initialisierung (Konstruktoraufrufe) erfolgt nur, wenn das statische Datenelement auf eine Weise verwendet wird, die seine Definition erfordert (z. B. Zuweisung).

Andererseits verwenden explizite Spezialisierungen explizite Deklarationen in Namespaces oder Klassen. die die Initialisierung angeordnet haben. Mit anderen Worten, ein spezialisiertes statisches Datenelement wird immer vor jeder Instanziierung seiner Klassenvorlage initialisiert.

Die Antwort

In Ihrem spezifischen Codebeispiel wird B::getHelper() aufgerufen löst die Initialisierung von mB und mInit aus, da getHelper einen Verweis auf mInit zurückgibt, was die Existenz des InitHelper erfordert.

Das Verlassen auf die Reihenfolge der Initialisierung ist jedoch undefiniertes Verhalten. Die richtige Lösung besteht darin, das statische Datenelement mInit explizit in Klasse B zu spezialisieren. Dadurch wird sichergestellt, dass das Hilfsobjekt immer erstellt wird und dass bei jeder nachfolgenden Instanziierung von B die statischen Datenelemente korrekt initialisiert werden.

Fazit

Zusammenfassend lässt sich sagen, dass die Initialisierung statischer Elemente in C-Vorlagen sorgfältige Überlegungen erfordert. Bei der impliziten Instanziierung werden nur Deklarationen instanziiert, keine Definitionen. Für eine geordnete und zuverlässige Initialisierung sollte beim Umgang mit Vorlagenklassen, die statische Datenelemente enthalten, eine explizite Spezialisierung in Betracht gezogen werden.

Das obige ist der detaillierte Inhalt vonWarum kann „B::getB()' „mB' in Vorlagenklassen mit statischen Mitgliedern nicht initialisieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage