7
votes

Singleton: Comment peut-on appeler deux fois?

J'ai demandé à un Question À propos de Singleton Mise en œuvre Il y a quelques minutes, j'ai une très bonne réponse de @LighessRacesinorbit.

Mais je ne peux pas comprendre pourquoi dans l'exemple suivant si j'instaine singleton dans variable inst son destructeur appelé deux fois? xxx

sortie: xxx

Démo en direct

Pour être plus correct, je comprends pourquoi est appelé deux fois. Mais je ne peux pas comprendre comment peut-il être appelé deux fois si après le premier destructeur, l'instance de la classe a été détruite? Pourquoi il n'y a pas d'exception?

ou il n'était pas détruit? Pourquoi?


7 commentaires

Ajouter singleton (singleton const &) {std :: cout << "Copier la construction! \ N"; } à votre exemple et tout sera révélé.


Vous devriez rendre la classe non copiable et non mobile: singleton (singleton const &) = Supprimer; Singleton (singleton &&) = Supprimer; Singleton & opérateur = (singleton const &) = Supprimer; Opérateur Singleton = (singleton &&) = Supprimer;


Vous avez Deux Instances de Singleton Tapez votre programme. One est statique intérieure getinstance . Un autre est local intérieur principal . Chaque objet est détruit éventuellement. D'où deux appels destructeurs. Pourquoi est-ce que cela vous surprend que le destructeur est appelé deux fois?


@Ant parce que je suis débutant. Merci à tous. Maintenant, je comprends.


Je recommande de lire ceci: JALF.DK/BLOG/2010/03/...


Désolé, j'aurais dû supprimer le constructeur de copie et l'opérateur d'affectation. Bien que dans un sens, je suis content que je ne l'ai pas fait parce que tu dois demander ceci :)


@LightnessRacesinorbit et après avoir obtenu l'écriture à l'aise et utiliser Singleton, ils peuvent procéder à Apprentissage à éviter d'utiliser :)


4 Réponses :


18
votes

Cette ligne xxx pré>

doit être p>

Singleton(Singleton const&) = delete;             // Copy construct
Singleton(Singleton&&) = delete;                  // Move construct
Singleton& operator=(Singleton const&) = delete;  // Copy assign
Singleton& operator=(Singleton &&) = delete;      // Move assign


3 commentaires

Ouais. Si vous voulez vraiment qu'un singleton soit un singleton, vous devrez supprimer son constructeur de copie ou le faire privé.


Il n'est pas nécessaire de supprimer explicitement les versions de référence RValue, car le compilateur ne les générera pas automatiquement.


Il n'y a pas besoin pour beaucoup de choses



8
votes

La ligne

void operator=( const Singleton& ) = delete;


5 commentaires

@ πννταῥεῖ en théorie, vous avez raison, mais pour un singleton, il ne devrait pas exister d'une seconde instance à céder à;) Mais oui, il est possible de finir avec un code stupide qui déclenche accidentellement la mission, je modifierai le réponse.


@DanielEfrey, je suppose que l'on peut faire singleton :: getinstance () = singleton :: getinstance (); , qui est vraiment hors limites, mais toujours faisable;)


@Vsoftco Oui, mais ce n'est plus un accident, il demande des ennuis. :-RÉ


Si cela peut être fait, on finit par le faire: D Mais je suis totalement d'accord, cela demande des ennuis.


@vsoftco C'est pourquoi je envisage d'être légèrement paranoïaque à être un atout pour un développeur de logiciels :-p



3
votes

Essayez d'ajouter un copy-constructeur public: xxx

Votre sortie deviendra: xxx

Il y a deux "singletons" vivants parce que celui de getinstance () a été copié. Pour éviter de copier par inadvertance singletons, vous devez supprimer le constructeur de copie et les opérateurs d'affectation: xxx


2 commentaires

Il y a quelque chose de satisfaire de voir la production de débogage que j'ai choisi arbitrairement se frayer un chemin à travers deux personnes à un autre post :)


Cela semble tellement heureux aussi!



2
votes

Vous pouvez cacher le singleton dans une classe normale ne présentant pas sa nature statique: xxx


0 commentaires