"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Pourquoi l’initialisation des membres statiques dans les classes basées sur un modèle se comporte-t-elle différemment ?

Pourquoi l’initialisation des membres statiques dans les classes basées sur un modèle se comporte-t-elle différemment ?

Publié le 2024-11-14
Parcourir:723

 Why Does Static Member Initialization in Templated Classes Behave Differently?

Complications liées à l'initialisation des membres statiques dans les classes basées sur des modèles

L'initialisation des membres statiques en C est une technique largement utilisée, mais elle peut devenir complexe lorsqu'il s'agit de classes modélisées. Dans les classes sans modèle, une structure d'assistance imbriquée peut être utilisée pour l'initialisation, mais cette approche ne suffit pas lorsque la classe englobante est basée sur un modèle.

Considérez l'exemple simplifié suivant :

struct A
{
    static std::string mA;
    static InitHelper mInit;

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


template
struct B
{
    static std::string mB;
    static InitHelper mInit;

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper() { return mInit; }
};
template
std::string B::mB;
template
typename B::InitHelper B::mInit;

int main()
{
    std::cout ::getB() ::getHelper(); // [2]
}

Comportement attendu :

Lorsque [1] n'est pas commenté et [2] est commenté, nous nous attendons à ce que B::mB soit initialisé à " Bonjour, je suis B.". Cependant, cela ne se produit pas.

Comportement réel :

  • Avec [1] et [2] commentés : Aucun effet secondaire se produire.
  • With [1] non commenté : B::getB() renvoie un vide string.
  • Avec [1] et [2] non commentés : B::mB est correctement initialisé.
  • Avec [1] commenté et [2] non commenté : Une erreur de segmentation se produit lors de l'initialisation statique.

Raison de l'erreur Différence :

Selon la norme ISO/IEC C 2003, le membre du modèle est implicitement instancié lorsqu'il est référencé dans un contexte qui nécessite que sa définition existe. Toutefois, l’initialisation des données membres statiques (et tous les effets secondaires associés) ne se produisent que lorsque les données membres statiques sont explicitement utilisées. Cela signifie que si un membre de modèle est uniquement référencé dans des modèles non instanciés ou dans d'autres contextes qui ne nécessitent pas son instanciation complète, ses données membres statiques ne seront pas initialisées.

Dans l'exemple, B:: getB() nécessite que B::mB existe, mais cela force uniquement l'instanciation de la déclaration du modèle membre, pas sa définition (y compris l'initialiseur). En revanche, B::getHelper() nécessite la définition de B::mInit car il renvoie une référence à celui-ci.

Solution:

La norme interdit que les définitions des membres de données statiques de modèles de classe explicitement spécialisés aient une initialisation ordonnée, tandis que les autres membres de données statiques de modèles de classe ont une initialisation non ordonnée. Pour garantir un ordre d'initialisation cohérent, il faut utiliser des spécialisations explicites.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3