De ce que je comprends, je suis capable de "désactiver" la copie et l'affectation de mes objets en définissant le constructeur de copie privé et en fonction de l'opérateur d'affectation: mais quelle est l'utilisation de cela? J'apprécierais si vous pouviez décrire la situation, dans laquelle il serait raisonnable / utile de "désactiver" l'affectation et le constructeur de copie de cette manière. P> p>
Est-il considéré comme une mauvaise pratique? P>
5 Réponses :
Lorsque vous essayez de mettre en œuvre un motif singleton, il est parfaitement acceptable d'utiliser un constructeur privé car il est censé être instancié à l'intérieur de lui-même et de nulle part ailleurs. Une fois invoqué, le constructeur ne peut pas être révoqué. Donc, le constructeur est invoqué uniquement après avoir vérifié si la condition singleton satisfaite. P>
C'est utile quand il n'a pas de sens que votre objet soit copié. Il n'est certainement pas considéré comme une mauvaise pratique. P>
Par exemple, si vous avez une classe qui représente une connexion réseau, il n'a pas de sens de copier cet objet. Une autre fois que vous voudrez peut-être qu'une classe soit non gêne, c'est si vous aviez une classe représentant un joueur dans un jeu multijoueur. Ces deux classes représentent des choses qui ne peuvent pas être copiées dans le monde réel, ou qui n'ont pas de sens à copier (une personne, une connexion). P>
En outre, si vous essayez de mettre en œuvre un singleton, sa procédure standard permet de rendre les objets non-copieux. P>
Merci, ça a du sens. Qu'en est-il de l'opérateur d'affectation?
@LiHo En général, si vous désactivez un pour désactiver l'autre. Si vous ne désactivez pas l'opérateur d'affectation, vous pouvez le faire: MyClass A, B; a = b; code> et si vous ne désactivez pas le constructeur de copie, vous pouvez faire
myClass B; MyClass A (b); code> Donc, si vous ne désactivez pas les deux, vous pouvez vous contourner l'autre d'être désactivé.
C'est une pratique assez courante. Il y a beaucoup d'exemples où la copie n'est pas appropriée. P>
Disons que votre objet représente une prise ouverte côté serveur (c'est-à-dire une connexion réseau entrante); Quelle serait la sémantique de faire une copie de cet objet? P>
De manière générale, une classe qui gère une ressource devrait être autre que de la sémantique de copie spécialisée. L'inverse est vrai aussi: toute classe qui est non copieuse ou nécessite une sémantique spécialisée de copie est la gestion d'une ressource. "Gérer une ressource" dans le C ++ Lingua dans la pratique signifie responsable de certains espaces en mémoire, ou pour une connexion à un réseau ou à une base de données, ou une poignée à un fichier, ou une transaction d'annulation, etc.
ressource La direction capture beaucoup d'exemples. Ce sont des responsabilités qui prennent une opération de préfixe, une opération suffixe et éventuellement une action entre les deux. La gestion de la mémoire, par exemple, implique d'acquérir une poignée à une adresse mémoire que nous allons gérer, peut-être gâcher avec cette mémoire et libérer enfin la poignée (parce que si vous aimez quelque chose, laissez-le libre). P> < Pré> xxx pré>
Cette classe parce que nous n'avons pas fourni une sémantique spécialisée de copie pour tout cela pour dire que lorsqu'une classe 'raise d'arrière est gérant une ressource Ensuite, vous devriez immédiatement savoir que vous devez gérer la copie. Vous devriez décider p> J'irais jusqu'ici et disons que la gestion des ressources est le seul cas où vous désactivez la copie ou de fournir une sémantique de copie spécialisée. Ceci est juste une autre perspective sur la règle de trois . P> p> La classe code> est presque correcte: elle acquiert automatiquement l'espace mémoire sous-jacent et le libère automatiquement, même si une exception se propage quelque temps après avoir acquis sa ressource. Mais considérez ce scénario: p>
mémoire code>, le compilateur fournit son propre constructeur de copie et copier l'affectation. Celles-ci font la chose
m2 = m1 code> signifie
m2.p = m1.p code>, tel que les deux pointeurs pointeront à la même adresse. Il est faux parce que lorsque
m2 code> est hors de portée, il libère sa ressource comme un bon objet responsable, et lorsque
m1 code> est hors de portée de la portée qui libère sa ressource, cette même ressource
M2 CODE> a déjà libéré, complétant un double-Supprimer - un scénario de comportement non défini notoire. De plus, en C ++, il est extrêmement facile de faire des copies d'un objet sans même remarquer: une fonction prenant son paramètre par valeur, renvoyant son paramètre par valeur ou prenant son paramètre par référence, mais appelant une autre fonction qui prend elle-même (ou renvoie) son paramètre par valeur ... Il est plus facile de supposer que les choses vont em> vont être copiées. p>
Lorsque vous êtes autorisé à créer une instance d'objet uniquement après avoir vérifié comme dans le cas de Singleton, vous avez besoin de constructeurs privés. Lorsque le constructeur est appelé l'instance d'objet sera appelé, puis il n'ya aucun point de vérifier s'il existe déjà une autre instance. Donc, ce que nous faisons, c'est appeler une fonction de membre de la classe à partir de la fonction principale et à l'intérieur de cette fonction de fonction si une autre instance est déjà dans la mémoire. Si non constructeur est appelé. sinon avorté. Vérifiez les classes Singleton ou d'autres classes protégées où les données de l'objet doivent être sécurisées et ne doivent pas être autorisées à copier. P>
Vérifiez également ceci: classe Singleton en C ++ P>
Un singleton serait un exemple.