7
votes

Destruction automatique de l'objet statique

Pourquoi ne pas c ++ créer / détruire un élément statique d'un type de modèle.

Observez l'exemple suivant: p>

#include <iostream>

struct Dump {
  Dump() {
    std::cout << "CTOR" << std::endl;
  }
  ~Dump() {
    std::cout << "DTOR" << std::endl;
  }
};

template <typename T> struct X {
  static Dump dump;
};

template <typename T> Dump X<T>::dump;

struct A : X<A> {
};

int main() {
  A a;
  return 0;
}


6 commentaires

Où instanciez-vous l'un de ces types?


Est-ce que je dois vraiment? Quoi qu'il en soit, A est instancié dans principal , je modifierai.


@Vjo: J'ai essayé de laisser ce qui n'est pas essentiel au problème. Bien sûr, j'ai un principal , voir mon édition (sinon je pourrais construire un exécutable, puis-je?).


EMMM. Quel comportement observent-vous?


Modèle Dump X :: Dump; devrait être un modèle Dump X :: Dump;


@Mat: Merci pour l'indice, je dois l'avoir négligé tout en copiant des choses sur le site. Corrigé maintenant.


3 Réponses :


4
votes

Il n'est pas instancié, sauf si utilisé. Cela fonctionne: xxx

également, corrigez l'erreur de compilation: xxx


5 commentaires

Merci, maintenant ça fait l'affaire. Homme, C'est Qu'est-ce que j'appelle un comportement dangereux!


Cela ressemble plus à l'optimisation


Vous n'avez pas besoin d'écrire (void) a.dump . Parce que A A entraînera une instanciation du modèle de classe qui créera à son tour l'instance de membre statique.


@Nawaz: L'ensemble du point de la question est que a ne ! Au moins pas implicitement. Ce que j'ai fait maintenant, c'est de mentionner le membre dans a :: a () .


J'ai été mordu par cela une fois, et j'ai appris. Il suffit de le prendre tel quel (j'ai examiné la norme, mais je n'ai pas trouvé les paragraphes pertinents)



4
votes

Les membres des modèles de classe ne sont instanciés que si elles sont nécessaires; Dans ce cas, rien ne fait référence au député statique, il n'est donc pas instancié, même si le modèle de classe elle-même est.

Vous constaterez que mettre la déclaration x ::/mp; quelque part entraînera l'instanciation du membre et un objet créé et détruit.


0 commentaires

5
votes

J'ai trouvé quelque chose dans § 14.7.1 Instanciation implicite .

1 / [...] l'instanciation implicite d'une spécialisation de modèle de classe causes l'instanciation implicite des déclarations, mais non de Les définitions ou les arguments par défaut, des fonctions de membre de la classe, des classes de membre, des énumérations de membres scopés, membres de données statiques et des modèles membres. [...]

Il continue dans la deuxième note:

2 / Sauf si un membre d'un modèle de classe ou d'un modèle de membre a été explicitement instancié ou explicitement spécialisé, la spécialisation du membre est implicitement instanciée lorsque la spécialisation est référencée dans un contexte qui nécessite la la définition des membres exister; en particulier, l'initialisation (et tout effets secondaires associés) d'un élément de données statique ne se produit pas à moins que l'élément de données statique est utilisé lui-même d'une manière qui nécessite la définition de l'élément de données statique à exister.

Par conséquent, sauf si vous l'utilisez, il ne faut pas être instancié . Ce n'est pas une optimisation, juste une conformité standard [N3092].


0 commentaires