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

source:php.cn
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