2011-01-10 15 views
48

Eventuali duplicati:
What is the use of making constructor private in a class?privato costruttore

Dove abbiamo bisogno costruttore privato? Come possiamo istanziare una classe con un costruttore privato?

+2

Vedere anche http://stackoverflow.com/questions/2062560/questo-è-del-uso-del-making-constructor-private-in-a-class – StuartLC

+0

Ben individuato, anche la risposta accettata a questa domanda è inutile a C++ -> è pessimo gusto creare una classe di funzioni statiche in C++, non siamo vincolati dalla mentalità "pura" OOP. –

+0

http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class/16547184#16547184 –

risposta

64

Il costruttore privato indica che un utente non può creare direttamente un'istanza di una classe. Invece, puoi creare oggetti usando qualcosa come lo Named Constructor Idiom, dove hai le funzioni di classe static che possono creare e restituire istanze di una classe.

Il Named Constructor Idiom consente un uso più intuitivo di una classe. L'esempio fornito alle FAQ C++ riguarda una classe che può essere utilizzata per rappresentare più sistemi di coordinate.

Questo viene estratto direttamente dal collegamento. È una classe che rappresenta punti in diversi sistemi di coordinate, ma può essere utilizzata per rappresentare sia i punti di coordinate rettangolari che polari, in modo da renderlo più intuitivo per l'utente, diverse funzioni sono utilizzate per rappresentare quale sistema di coordinate rappresenta Point restituito.

#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)); } 

Ci sono stati un sacco di altre risposte che si adattano anche lo spirito del motivo per cui i costruttori privati ​​sono sempre più utilizzati in C++ (pattern Singleton tra di loro).

Un'altra cosa che puoi fare con questo è prevent inheritance of your class, poiché le classi derivate non saranno in grado di accedere al costruttore della classe. Ovviamente, in questa situazione, hai ancora bisogno di una funzione che crei istanze della classe.

+1

Non sono sicuro, ma sarebbe bello avere un copy ctor. Non ne sono sicuro, a causa di RVO. –

+3

@Pawel - L'esempio di FAQ C++ non definisce il costruttore di copia per 'Point' perché la classe ha solo membri primitivi (due' float'), quindi il costruttore di copie predefinito del compilatore (che fa copie superficiali) è sufficiente per l'esempio. – birryree

+1

+1 Infine, un esempio che non è Singleton o Factory. I costruttori denominati sembrano molto più utili. – chrisaycock

29

Un uso comune è nel modello singleton in cui si desidera che esista solo una istanza della classe. In tal caso, è possibile fornire un metodo static che esegue l'istanziazione dell'oggetto. In questo modo è possibile controllare il numero di oggetti istanziati di una particolare classe.

+17

+1. Vengo sempre sottovalutato quando menziono un singleton come caso per un particolare idioma. Non voglio che questo accada a te! :) –

2

È comune quando si desidera implementare un singleton. La classe può avere un "metodo factory" statico che controlla se la classe è già stata istanziata e chiama il costruttore se non lo ha.

5

È ragionevole rendere privato il costruttore se esistono altri metodi che possono produrre istanze. Esempi ovvi sono i pattern Singleton (ogni chiamata restituisce la stessa istanza) e Factory (ogni chiamata di solito crea una nuova istanza).

1

Ad esempio, è possibile richiamare un costruttore privato all'interno di una classe di amici o di una funzione di amicizia.

Singleton pattern di solito lo utilizza per assicurarsi che nessuno crei più istanze del tipo desiderato.

6

Il costruttore privato è utile quando non si desidera che la classe venga istanziata dall'utente. Per istanziare tali classi, è necessario dichiarare un metodo statico, che fa il 'nuovo' e restituisce il puntatore .

Non è possibile inserire nei contenitori STL una classe con operatori privati, in quanto richiedono un duplicatore.

1

Un uso comune è per le classi di soluzione modello-typedef come segue:

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

Ovviamente un costruttore pubblico non attuata avrebbe funzionato entrava, ma un construtor privata solleva un errore di tempo di compilazione, invece di un errore di tempo di collegamento , se qualcuno tenta di instaziare MyLibrariesSmartPointer<SomeType> anziché MyLibrariesSmartPointer<SomeType>::type, che è desiderabile.

Problemi correlati