Maison > Article > développement back-end > Comment forcer l'initialisation d'un membre statique en C sans référencement explicite ?
Comment forcer l'initialisation d'un membre statique
Un comportement souvent négligé en C est qu'il n'est pas garanti que les membres statiques soient initialisés automatiquement. On peut s'attendre à ce que le membre soit initialisé à la première instanciation de la classe concrète. Cependant, comme le suggère la citation de la norme, cela ne se produit que lorsque le membre statique est activement utilisé :
"* en particulier, l'initialisation (et tous les effets secondaires associés) d'un membre de données statique ne se produit pas. à moins que le membre de données statique soit lui-même utilisé d'une manière qui nécessite que la définition du membre de données statique existe. "
Le problème
Considérez le code suivant :
<code class="cpp">template <class D> char register_() { return D::get_dummy(); // static function } template <class D> struct Foo { static char const dummy; }; template <class D> char const Foo<D>::dummy = register_<D>(); // static member initialized with `register_<D>()` struct Bar : Foo<Bar> { static char const get_dummy() { return 42; } };</code>
Intuitivement, on pourrait s'attendre à ce que dummy soit initialisé lors de l'instanciation de Bar. Cependant, cela n'arrive pas.
La question
Comment forcer l'initialisation de dummy sans nécessiter une instance de Bar ou Foo ? De plus, la solution ne doit pas nécessiter un référencement explicite du membre par l'utilisateur de Foo.
Solutions potentielles
Solution 1 (impact minimal sur la classe dérivée)
La modification suivante de la méthode get_dummy() de Bar forcera l'initialisation de dummy :
<code class="cpp">static char const get_dummy() { (void)dummy; return 42; }</code>
Solution 2 (Aucune modification de la classe dérivée)
Cette solution utilise une métaprogrammation de modèles :
<code class="cpp">template<typename T, T> struct value { }; template<typename T> struct HasStatics { static int a; // we force this to be initialized typedef value<int&, a> value_user; }; template<typename T> int HasStatics<T>::a = /* whatever side-effect you want */ 0;</code>
Ou, cela peut être fait sans introduire de membres supplémentaires :
<code class="cpp">template<typename T, T> struct var { enum { value }; }; template<typename T> struct HasStatics { static int a; // we force this to be initialized static int b; // and this char user :var<int&, a>::value, :var<int&, b>::value; }; template<typename T> int HasStatics<T>::a = /* whatever side-effect you want */ 0; template<typename T> int HasStatics<T>::b = /* whatever side-effect you want */ 0;</code>
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!