2009-06-29 11 views

Respuesta

73

Cuando una clase es (destinada como) una clase abstracta, un constructor protegido es exactamente correcto. En esa situación, no desea que los objetos sean instanciados de la clase, sino solo usarlos para heredar.

Existen otros casos de uso, como cuando un cierto conjunto de parámetros de construcción debe limitarse a las clases derivadas.

+7

+1 Pero no necesariamente tiene que ser una clase abstracta. Sin embargo, a menudo es el caso. – ralphtheninja

+4

¿No es suficiente declarar que una función es puramente virtual para definir una clase base? O lo anterior es en ausencia de la función virtual pura. ¿Qué es un evento de creación para una clase Derivada de una clase abstracta de este tipo? –

+0

@Henk Holterman Ciertamente sí; consulte la Sección 10.4 del Estándar C++, titulada "Clases abstractas" –

11

un uso podría ser patrones de fábrica

6

Un constructor protegido significa que los miembros solamente derivados pueden construir instancias de la clase (y casos derivados) que utilizan ese constructor. Esto suena un poco al huevo y la gallina, pero a veces es útil cuando se implementan fábricas de clase.

+3

Técnicamente, esto se aplica solo si TODOS los ctors están protegidos. – MSalters

+1

las clases de amigo también pueden llamar al constructor protegido (no solo a las clases derivadas). –

+0

...y el uso de una clase de amigo que llame al constructor protegido sería en el caso de un objeto que tiene miembros que son constantes (establecidos por el constructor) pero deben ser públicos, pero nunca deben ser establecidos por ningún otro acceso público, garantiza que el objeto no se creará en otro lugar y, por lo tanto, los datos tampoco se modificarán en ningún otro lado. – osirisgothra

3

Para permitir que una subclase utilice un constructor que no debe ser accesible a un instanciador directamente.

3

Usted puede usarlo para limitar las clases que podrían crear, por ejemplo:

class Level 
{ 
private: 

Level(); 
¨Level(); 

friend class LevelManager; 
}; 

La única clase que puede crear una instancia de ella es la clase LevelManager, por lo que siempre sabrá que el nivel instancia se crea en el LevelManager.

+0

Si bien es cierto, es un constructor privado, no protegido. – David

+0

ahaha lo siento, he leído mal. ¿Debo eliminar mi publicación? –

7

Los constructores no públicos son útiles cuando hay requisitos de construcción que no pueden ser garantizados únicamente por el constructor. Por ejemplo, si un método de inicialización necesita ser llamado justo después del constructor, o si el objeto necesita registrarse con algún objeto contenedor/administrador, esto debe hacerse fuera del constructor. Al limitar el acceso al constructor y proporcionar solo un método de fábrica, puede asegurarse de que cualquier instancia que un usuario reciba cumpla con todas sus garantías. Esto también se usa comúnmente para implementar un Singleton, que en realidad es solo otra garantía que hace la clase (que solo habrá una sola instancia).

La razón para hacer que el constructor esté protegido, en lugar de privado, es el mismo que para hacer que cualquier otro método o campo esté protegido en lugar de privado: para que pueda ser heredado por los niños. Quizás desee un método de fábrica público, no virtual en la clase base, que devuelve referencias a instancias de las clases derivadas; las clases derivadas, obviamente, quieren acceso a los constructores originales, pero todavía no desea crearlos fuera de su fábrica.

2

Para métodos de fábrica con efectos secundarios.

class mine { 

    private: 
    mine() {}; 

    protected: 
    mine(int id) : m_id(id) {}; 

    int m_id; 
    static int m_count; 

    public: 
    static mine* CreateOneOfMe() { 
     return mine(m_count++); 
    } 

    int GetId() { return m_id; } 

}; 

Esto crea instancias de la clase y garantiza que cada una de ellas tiene una identificación entera de incremento única. Tenga en cuenta que si el constructor que desea utilizar no es el predeterminado, también debe ocultar el predeterminado.

5

Un constructor protegido se puede usar para hacer que una clase sea efectivamente abstracta cuando ninguno de sus métodos es puro-virtual.

No es muy abstracto en el sentido C++ ya que las clases de amigos todavía pueden usarlo sin sobrescribir, pero entonces tendrías que declararlos.

Cuestiones relacionadas