Maison >développement back-end >C++ >Pourquoi `B::getB()` ne parvient-il pas à initialiser `mB` dans les classes modélisées avec des membres statiques ?
En C, l'initialisation des membres statiques pour les structures d'assistance imbriquées fonctionne généralement sans problème pour les classes sans modèle. Cependant, lorsque la classe englobante est modélisée, une bizarrerie potentielle survient si l'objet d'assistance n'est pas accessible dans le code principal.
Considérez l'exemple simplifié suivant :
<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>
Ici, InitHelper imbriqué initialise le membre statique mA pour A et mB pour B.
Le problème se pose lorsque nous essayons d'initialiser les membres dans une classe B basée sur un modèle. Utilisation de la méthode getB , comme indiqué ci-dessous, ne déclenche pas l'initialisation de mB :
<code class="cpp">std::cout << "B = " << B<int>::getB() << std::endl;
Cela se produit car, selon la norme ISO/IEC C 2003 (14.7.1), l'initialisation d'un membre de données statique se produit uniquement lorsque le membre est lui-même utilisé d'une manière qui nécessite sa définition. Dans ce cas, puisque mB n'est référencé que dans la méthode getB() de la classe modélisée, le compilateur n'instancie pas implicitement sa définition.
Pour comprendre le compilateur comportement, il est important de clarifier le concept d’instanciation implicite. Pour les données membres statiques dans les modèles, une instanciation implicite instancie les déclarations mais pas les définitions. L'initialisation réelle (appels du constructeur) ne se produit que lorsque le membre de données statique est utilisé d'une manière qui nécessite sa définition (par exemple, affectation).
D'autre part, les spécialisations explicites utilisent des déclarations explicites dans des espaces de noms ou des classes, qui ont ordonné l'initialisation. En d'autres termes, une donnée membre statique spécialisée est toujours initialisée avant toute instanciation de son modèle de classe.
Dans votre exemple de code spécifique, en appelant B Cependant, s'appuyer sur l'ordre d'initialisation est un comportement indéfini. La solution correcte consiste à spécialiser explicitement le membre de données statiques mInit dans la classe B. Cela garantira que l'objet d'assistance est toujours créé et que toute instanciation ultérieure de B verra ses membres de données statiques initialisés correctement. Pour résumer, l'initialisation des membres statiques dans les modèles C nécessite un examen attentif. L'instanciation implicite instancie uniquement les déclarations, pas les définitions. Pour une initialisation ordonnée et fiable, une spécialisation explicite doit être envisagée lorsqu'il s'agit de classes basées sur un modèle contenant des données membres statiques. 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!Conclusion