web-dev-qa-db-fra.com

constructeur privé

Duplicata possible:
Quelle est l'utilité de rendre le constructeur privé dans une classe?

Où avons-nous besoin d'un constructeur privé? Comment instancier une classe ayant un constructeur privé?

49
Atul

Un constructeur privé signifie qu'un utilisateur ne peut pas instancier directement une classe. Au lieu de cela, vous pouvez créer des objets en utilisant quelque chose comme Named Constructor Idiom , où vous avez des fonctions de classe static qui peuvent créer et renvoyer des instances d'une classe.

L'idiome du constructeur nommé est destiné à une utilisation plus intuitive d'une classe. L'exemple fourni dans C++ FAQ est pour une classe qui peut être utilisée pour représenter plusieurs systèmes de coordonnées.

Ceci est tiré directement du lien. Il s'agit d'une classe représentant des points dans différents systèmes de coordonnées, mais elle peut être utilisée pour représenter à la fois des points de coordonnées rectangulaires et polaires, donc pour la rendre plus intuitive pour l'utilisateur, différentes fonctions sont utilisées pour représenter le système de coordonnées renvoyé Point représente.

 #include <cmath>               // To get std::sin() and std::cos()

 class Point {
 public:
   static Point rectangular(float x, float y);      // Rectangular coord's
   static Point polar(float radius, float angle);   // Polar coordinates
   // These static methods are the so-called "named constructors"
   ...
 private:
   Point(float x, float y);     // Rectangular coordinates
   float x_, y_;
 };

 inline Point::Point(float x, float y)
   : x_(x), y_(y) { }

 inline Point Point::rectangular(float x, float y)
 { return Point(x, y); }

 inline Point Point::polar(float radius, float angle)
 { return Point(radius*std::cos(angle), radius*std::sin(angle)); }

Il y a eu beaucoup d'autres réponses qui correspondent également à l'esprit de la raison pour laquelle les constructeurs privés sont jamais utilisés en C++ (modèle Singleton parmi eux).

Une autre chose que vous pouvez en faire est de empêcher l'héritage de votre classe , car les classes dérivées ne pourront pas accéder au constructeur de votre classe. Bien sûr, dans cette situation, vous avez toujours besoin d'une fonction qui crée des instances de la classe.

64
wkl

Une utilisation courante est dans le modèle singleton où vous voulez qu'une seule instance de la classe existe. Dans ce cas, vous pouvez fournir une méthode static qui effectue l'instanciation de l'objet. De cette façon, le nombre d'objets instanciés d'une classe particulière peut être contrôlé.

29
Naveen

le constructeur privé est utile lorsque vous ne voulez pas que votre classe soit instanciée par l'utilisateur. Pour instancier de telles classes, vous devez déclarer une méthode statique, qui fait le "nouveau" et retourne le pointeur.

Une classe avec des ctors privés ne peut pas être placée dans les conteneurs STL, car ils nécessitent un ctor de copie.

6
vrdhn

Il est raisonnable de rendre le constructeur privé s'il existe d'autres méthodes pouvant produire des instances. Des exemples évidents sont les modèles Singleton (chaque appel renvoie la même instance) et Factory (chaque appel généralement crée une nouvelle instance).

5
Andrey

Il est courant lorsque vous souhaitez implémenter un singleton. La classe peut avoir une "méthode d'usine" statique qui vérifie si la classe a déjà été instanciée et appelle le constructeur si ce n'est pas le cas.

2
unwind

Par exemple, vous pouvez invoquer un constructeur privé dans une classe amie ou une fonction amie.

modèle Singleton l'utilise généralement pour s'assurer que personne ne crée plus d'instances du type voulu.

1
Simone

Une utilisation courante est pour les classes de contournement template-typedef comme suit:

template <class TObj>
class MyLibrariesSmartPointer
{
  MyLibrariesSmartPointer();
  public:
    typedef smart_ptr<TObj> type;
};

De toute évidence, un constructeur public non implémenté fonctionnerait également, mais un constructeur privé soulève une erreur de temps de compilation au lieu d'une erreur de temps de liaison, si quelqu'un essaie de lancer MyLibrariesSmartPointer<SomeType> au lieu de MyLibrariesSmartPointer<SomeType>::type, ce qui est souhaitable.

1
smerlin