Maison > développement back-end > C++ > Comment forcer l'initialisation d'un membre statique en C sans référencement explicite ?

Comment forcer l'initialisation d'un membre statique en C sans référencement explicite ?

DDD
Libérer: 2024-10-31 05:38:01
original
442 Les gens l'ont consulté

 How to Force Initialization of a Static Member in C   Without Explicit Referencing?

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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 de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal