2011-01-10 4 views
48

Mögliche Duplizieren:
What is the use of making constructor private in a class?privaten Konstruktor

Wo brauchen wir privaten Konstruktor? Wie können wir eine Klasse mit einem privaten Konstruktor instanziieren?

+2

Siehe auch http://StackOverflow.com/Questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class – StuartLC

+0

Gut entdeckt, auch die akzeptierte Antwort auf diese Frage ist nutzlos für C++ -> es ist ein schlechter Geschmack, eine Klasse von statischen Funktionen in C++ zu erstellen, wir sind nicht durch "reine" OOP Denkweise eingeschränkt. –

+0

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

Antwort

64

Privater Konstruktor bedeutet, dass ein Benutzer eine Klasse nicht direkt instanziieren kann. Stattdessen können Sie Objekte erstellen, die etwas wie die Named Constructor Idiom verwenden, wo Sie static Klassenfunktionen haben, die Instanzen einer Klasse erstellen und zurückgeben können.

Der Named Constructor Idiom ist für intuitive Nutzung einer Klasse. Das in den C++ - FAQ bereitgestellte Beispiel bezieht sich auf eine Klasse, mit der mehrere Koordinatensysteme dargestellt werden können.

Dies wird direkt von der Verbindung gezogen. Es ist eine Klasse, die Punkte in verschiedenen Koordinatensystemen darstellt, aber es kann zur Darstellung sowohl von Rechteck- als auch von Polarkoordinatenpunkten verwendet werden. Um es für den Benutzer intuitiver zu gestalten, werden verschiedene Funktionen verwendet, um darzustellen, welches Koordinatensystem die zurückgegebene Point darstellt.

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

Es gibt viele andere Antworten gegeben, die auch den Geist, warum private Konstruktoren passen, werden in C++ je benutzt (Singleton-Muster unter ihnen).

Eine andere Sache, die Sie damit machen können, ist prevent inheritance of your class, da abgeleitete Klassen nicht in der Lage sein werden, auf den Konstruktor Ihrer Klasse zuzugreifen. In dieser Situation benötigen Sie natürlich noch eine Funktion, die Instanzen der Klasse erzeugt.

+1

Nicht sicher, aber es wäre gut, Kopie ctor zu haben. Ich bin mir nicht sicher, wegen RVO. –

+3

@Pawel - Das C++ - FAQ-Beispiel definiert den Kopierkonstruktor für 'Point' nicht, da die Klasse nur primitive Member (zwei' float') hat. Daher ist der Standardkopiekonstruktor des Compilers (der flache Kopien ausführt) ausreichend für das Beispiel. – birryree

+1

+1 Schließlich ein Beispiel, das kein Singleton oder Factory ist. Benannte Konstruktoren scheinen viel nützlicher zu sein. – chrisaycock

29

Eine häufige Verwendung ist in dem Singletonmuster wo Sie nur eine Instanz der Klasse wollen existieren. In diesem Fall können Sie eine static-Methode angeben, die die Instanziierung des Objekts durchführt. Auf diese Weise kann die Anzahl der instanziierten Objekte einer bestimmten Klasse gesteuert werden.

+17

+1. Ich werde immer downvoted, wenn ich ein Singleton als Fall-Verwendung für ein bestimmtes Idiom erwähne. Ich will nicht, dass dir das passiert! :) –

2

Es ist üblich, wenn Sie ein Singleton implementieren möchten. Die Klasse kann eine statische "Factory-Methode" haben, die prüft, ob die Klasse bereits instanziiert wurde, und den Konstruktor aufruft, falls dies nicht der Fall ist.

5

Es ist vernünftig Konstruktor privat zu machen, wenn es andere Methoden, die Instanzen erzeugen können. Offensichtliche Beispiele sind Muster Singleton (jeder Aufruf gibt die gleiche Instanz zurück) und Factory (jeder Aufruf normalerweise neue Instanz erstellen).

1

Zum Beispiel können Sie einen privaten Konstruktor innerhalb einer Freundesklasse oder einer Freundesfunktion aufrufen.

Singleton pattern in der Regel verwendet es, um sicherzustellen, dass niemand mehr Instanzen von der beabsichtigten Art erzeugt.

6

private Konstruktor sind nützlich, wenn Sie nicht wollen, Ihre Klasse von Benutzer instanziiert werden. Um solche Klassen zu instanziieren, müssen Sie eine statische Methode deklarieren, die das "neue" ausführt und den Zeiger zurückgibt.

Eine Klasse mit eigenem ctors kann nicht in den STL-Container gestellt werden, da sie eine Kopie Ctor erfordern.

1

Eine häufige Verwendung ist für die Template-typedef Abhilfe Klassen wie folgt vor:

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

Offensichtlich ein öffentlicher, nicht umgesetzt Konstruktor würde als gut funktionieren, aber eine private construtor wirft Fehler einen Fehler zur Kompilierzeit anstelle einer Verbindungszeit , wenn jemand versucht MyLibrariesSmartPointer<SomeType> statt MyLibrariesSmartPointer<SomeType>::type zu installieren, was wünschenswert ist.