Maison >développement back-end >C++ >Comment pouvez-vous initialiser de manière fiable des membres statiques dans des classes C basées sur un modèle à l'aide de structures d'assistance imbriquées ?

Comment pouvez-vous initialiser de manière fiable des membres statiques dans des classes C basées sur un modèle à l'aide de structures d'assistance imbriquées ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-30 05:43:021053parcourir

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

Initialisation des membres statiques dans les classes modélisées et les aides d'initialisation

En C, les membres statiques peuvent être initialisés à l'aide de structures d'assistance imbriquées. Bien que cette approche fonctionne bien pour les classes sans modèle, elle peut poser des problèmes dans les classes avec des paramètres de modèle.

Énoncé du problème

Considérez l'exemple suivant, où un assistant d'initialisation de membre statique est utilisé dans un classe basée sur un modèle :

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

Dans ce scénario, les observations suivantes sont faites :

  • Avec [1] et [2] commentés, le résultat est comme prévu : "A = Bonjour, je suis A.".
  • Avec [1] non commenté, le résultat est "A = Bonjour, je suis A.nB = " au lieu du "Bonjour, je suis B" attendu. ".
  • Avec [1] et [2] non commentés, le résultat est comme prévu : "A = Bonjour, je suis A.nB = Bonjour, je suis B.".
  • Avec [1] commenté et [2] non commenté, le programme segfaults à [3].

Explication

Le comportement inattendu provient du comportement de l'initialisation des membres statiques dans classes modélisées. Selon la norme ISO/IEC C 2003 (14.7.1), l'initialisation d'une donnée membre statique se produit uniquement si la donnée membre statique est elle-même utilisée d'une manière qui nécessite que sa définition existe.

  • Dans le cas de A, la donnée membre statique mA est explicitement référencée dans main, son initialisation se produit donc avant l'exécution de la fonction principale.
  • Dans le cas de B, accéder à B::getB() fait référence à B::mB, déclenchant son initialisation. Cependant, l'accès à B::getHelper() n'utilise pas directement B::mInit, renvoyant uniquement un alias à l'assistant d'initialisation.

Solution

Pour Pour éviter de recourir à une initialisation implicite et garantir un ordre d'initialisation cohérent, il est recommandé de spécialiser explicitement les données membres statiques dans le modèle de classe. Dans ce cas :

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

En spécialisant explicitement le membre de données statique pour chaque instanciation de la classe basée sur un modèle, l'initialisation est explicitement déclenchée et le comportement souhaité est obtenu sans avoir à recourir à l'assistant d'initialisation.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn