2011-01-10 29 views
48

Duplicar posible:
What is the use of making constructor private in a class?constructor privado

¿Dónde es necesario constructor privado? ¿Cómo podemos crear una instancia de una clase que tenga un constructor privado?

+2

Véase también http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class – StuartLC

+0

Bien manchado, también la respuesta aceptada a esta pregunta es inútil para C++ -> es de mal gusto crear una clase de funciones estáticas en C++, no estamos limitados por la mentalidad de POO "pura". –

+0

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

Respuesta

64

Constructor privado significa que un usuario no puede instanciar directamente una clase. En su lugar, puede crear objetos usando algo como Named Constructor Idiom, donde tiene static funciones de clase que pueden crear y devolver instancias de una clase.

The Named Constructor Idiom es para un uso más intuitivo de una clase. El ejemplo proporcionado en C++ FAQ es para una clase que se puede usar para representar sistemas de coordenadas múltiples.

Esto se extrae directamente del enlace. Es una clase que representa puntos en diferentes sistemas de coordenadas, pero puede usarse para representar puntos de coordenadas Rectangulares y Polares, por lo que para que sea más intuitivo para el usuario, se usan diferentes funciones para representar qué sistema de coordenadas representa el Point devuelto.

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

Ha habido una gran cantidad de otras respuestas que también se ajustan al espíritu de la razón por constructores privados se utilizan cada vez en C++ (patrón Singleton entre ellos).

Otra cosa que puedes hacer es prevent inheritance of your class, ya que las clases derivadas no podrán acceder al constructor de tu clase. Por supuesto, en esta situación, todavía necesita una función que crea instancias de la clase.

+1

No estoy seguro, pero sería bueno tener copia del ctor. No estoy seguro de eso aunque debido a RVO. –

+3

@Pawel - El ejemplo de C++ FAQ no define el constructor de copia para 'Point' porque la clase solo tiene miembros primitivos (dos' float'), por lo que el constructor de copiado predeterminado del compilador (que hace copias superficiales) es suficiente para el ejemplo. – birryree

+1

+1 Finalmente, un ejemplo que no es Singleton o Factory. Los constructores con nombre parecen mucho más útiles. – chrisaycock

29

Un uso común es en el patrón singleton en el que solo desea una instancia de la clase. En ese caso, puede proporcionar un método static que ejemplifica el objeto. De esta forma, se puede controlar el número de objetos instanciados de una clase en particular.

+17

+1. Siempre me siento desanimado cuando menciono un singleton como uso de un caso para un idioma en particular. ¡No quiero que te suceda! :) –

2

Es común cuando quiere implementar un singleton. La clase puede tener un "método de fábrica" ​​estático que verifica si la clase ya se ha instanciado y llama al constructor si no lo ha hecho.

5

Es razonable hacer al constructor privado si hay otros métodos que pueden producir instancias. Los ejemplos obvios son patrones Singleton (cada llamada devuelve la misma instancia) y Factory (cada llamada generalmente crea una nueva instancia).

1

Por ejemplo, puede invocar a un constructor privado dentro de una clase de amigo o una función de amigo.

Singleton pattern generalmente lo usa para asegurarse de que nadie crea más instancias del tipo previsto.

6

private constructor son útiles cuando no desea que su clase sea instanciada por el usuario. Para instanciar dichas clases, debe declarar un método estático, que hace el 'nuevo' y devuelve el puntero.

Una clase con ctors privados no se puede poner en los contenedores STL, ya que requieren una copia del ctor.

1

Un uso común es para las clases de solución plantilla typedef como siguiente:

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

Obviamente un constructor público no implementado funcionaría aswell, sino una Construtor privada plantea un error de tiempo de compilación en lugar de un error de tiempo de enlace , si alguien intenta instalar MyLibrariesSmartPointer<SomeType> en lugar de MyLibrariesSmartPointer<SomeType>::type, lo cual es deseable.

Cuestiones relacionadas