31 votes

A quoi sert le constructeur de copie privée en c ++

Pourquoi définir un constructeur de copie privée?

Quand c'est de faire le constructeur de copie et l'opérateur d'affectation de privé un bon modèle?

Si il n'y a pas de membres de la classe, qui sont des pointeurs ou des poignées pour un objet unique (nom de fichier), puis, wat d'autres cas, il a été privé constructeur de copie est une bonne idée?

Même question s'applique pour l'opérateur d'affectation. Étant donné que la majorité de C++ tourne autour de la copie d'objets et le passage par référence, existe-il des modèles qui impliquent la copie privée constructeur?

27voto

Eric Z Points 7160

Un exemple d'utilisation est le modèle singletonil ne peut exister qu'une seule instance d'une classe . Dans ce cas, vous devez rendre vos constructeurs et votre opérateur d'affectation = privé afin qu'il n'y ait aucun moyen de créer plus d'un objet. La seule façon de créer un objet consiste à utiliser votre fonction GetInstance (), comme indiqué ci-dessous.

 // An example of singleton pattern
class CMySingleton
{
public:
  static CMySingleton& GetInstance()
  {
    static CMySingleton singleton;
    return singleton;
  }

// Other non-static member functions
private:
  CMySingleton() {}                                  // Private constructor
  ~CMySingleton() {}
  CMySingleton(const CMySingleton&);                 // Prevent copy-construction
  CMySingleton& operator=(const CMySingleton&);      // Prevent assignment
};

int main(int argc, char* argv[])
{
  // create a single instance of the class
  CMySingleton &object = CMySingleton::GetInstance();

  // compile fail due to private constructor
  CMySingleton object1;
  // compile fail due to private copy constructor
  CMySingleton object2(object);
  // compile fail due to private assignment operator
  object1 = object;

  // ..
  return 0;
}
 

24voto

Tony D Points 43962

Certains objets représentent des entités qui ne peuvent pas ou ne devraient pas être copié. Par exemple, vous pouvez empêcher la copie d'un objet qui représente le fichier journal utilisé par une application, correspondant à l'attente qu'un seul fichier journal sera utilisé par toutes les parties du code. L'utilisation d'un accidentellement ou de manière inappropriée objet copié pourrait conduire à de contenu apparaissant dans le journal, l'inexactitude des enregistrements de journal en cours de taille, de multiples tentatives (échec) à "rouler" vers un nouveau nom de fichier journal ou renommer l'existant.

Une autre utilisation est de faire respecter la copie via une fonction virtuelle. Que les constructeurs ne peuvent pas être virtual, une pratique courante est d'empêcher l'accès direct au constructeur de copie et de fournir un virtual Base* clone() méthode qui retourne une copie du type à l'exécution à laquelle un pointeur de points. Cela empêche l'accidentel, le découpage qu' Base b(derived) présentent.

Un autre exemple: un mort-simple pointeur intelligent objet qui supprime simplement le pointeur de la donnée dans le constructeur: si elle ne prend pas en charge le comptage de référence ou une autre manière de gérer plusieurs propriétaires, et ne veut pas avoir de risque maladroit involontaire std::auto_ptr style de transfert de propriété, puis il suffit de cacher le constructeur de copie donne un super petit pointeur intelligent, rapide et efficace pour le nombre limité de cas où il est utilisable. Une erreur de compilation à propos de la tentative de copie, il serait effectivement demander au programmeur "hé - si vous voulez vraiment faire me changer pour un pointeur partagé, sinon dégage!".

5voto

tc. Points 23958

Un très mauvais exemple:

 class Vehicle : { int wheels; Vehicle(int w) : wheels(w) {} }

class Car : public Vehicle { Engine * engine; public Car(Engine * e) : Vehicle(4), engine(e) }

...

Car c(new Engine());

Car c2(c); // Now both cars share the same engine!

Vehicle v;
v = c; // This doesn't even make any sense; all you have is a Vehicle with 4 wheels but no engine.
 

Que signifie "copier" une voiture? (Une voiture est-elle un modèle de voiture ou un exemple de voiture? Est-ce que sa copie préserve l’immatriculation du véhicule?)

Que signifie affecter un véhicule à un autre?

Si les opérations sont dénuées de sens (ou simplement non implémentées), la procédure standard consiste à rendre le constructeur de copie et l'opérateur d'affectation privés, provoquant une erreur de compilation s'ils sont utilisés à la place d'un comportement étrange.

2voto

user396672 Points 1619

Une raison commune pour rendre le constructeur de copie et l'affectation de copie privés est de désactiver la mise en œuvre par défaut de ces opérations. Cependant, dans C ++ 0x, une syntaxe spéciale = delete est utilisée à cette fin. Ainsi, en C ++ 0x, la copie privée de ctor semble être réservée aux cas très exotiques.

Les copieurs et les assignations sont plutôt du sucre syntaxique; alors un tel "sucre privé" semble être le symptôme de la cupidité :)

1voto

Nicol Bolas Points 133791

Même si le contenu de l'objet n'est ni un pointeur ni une autre référence, il peut toujours être utile d'empêcher les personnes de copier l'objet. Peut-être que la classe contient beaucoup de données et que la copie est une opération trop lourde.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X