2009-10-16 19 views
7

yo no entiendo por completo este:herencia privada

class Base 
{ 
    public: 
    Base() 
    { 
     cout<<"Base" << endl; 
    } 

    virtual void call() 
    { 
     cout<<"Base call" << endl; 
    } 
}; 

class Derived: private Base 
{ 
    public:  
    Derived() 
    { 
     cout<<"Derived" << endl; 
    } 
}; 

int main(void) 
{ 
    Base *bPtr = new Derived(); // This is not allowed 
} 

¿Es porque alguien podría llamar call() usando bPtr que en realidad se hace en objeto derivado? ¿O hay alguna otra razón?

Respuesta

18

de una comprensión común de la herencia, ‘la herencia privada’ C++’es un término equivocado terrible: es no herencia (por lo que todo lo que fuera de la clase se refiere), pero un detalle de implementación completa de la clase.

Visto desde el exterior, la herencia privada es más o menos lo mismo que la composición. Solo en el interior de la clase obtienes una sintaxis especial que recuerda más a la herencia que a la composición.

Sin embargo, hay una advertencia: C++ sintácticamente trata esto como herencia, con todos los beneficios y problemas que esto conlleva, como scope visibility and accessibility. Por otra parte, los moldes de tipo C (! Pero no echó C++) en realidad ignora la visibilidad y por lo tanto tiene éxito en la fundición de su puntero a DerivedBase:

Base* bPtr = (Base*) new Derived(); 

hace falta decir que este es el mal .

+7

Es herencia de implementación en lugar de herencia de interfaz. –

+0

@Laurence: cierto, pero eso es solo una terminología discutiendo. Me preocupaba la visión de afuera de la clase. –

+1

"_it is not inheritance_" Absolutamente incorrecto. ** Es ** herencia, con acceso privado. – curiousguy

0

Con herencia privada, pierde la opción de tratar su objeto derivado como un objeto de su clase base.

1

Si hereda en privado cualquier código que requiera la conversión de Derived * a Base * debe ser miembro o amigo de la clase Derived.

+0

Gracias por las respuestas, pero en realidad quería saber por qué no permitieron que esto sucediera. –

+0

@nitinsoman Porque ** tu ** escribió 'privado'. Eso es lo que significa acceso privado ... ¿cuál es tu pregunta? – curiousguy

9

Porque private significa "detalle de implementación", lo que hace que el hecho de Derived derive de Base un detalle de implementación.

La herencia privada no es herencia de interfaz, sino herencia de implementación. No implementa una relación "Is-A", sino una relación "Is-Implemented-Using". Derived no es un Base en lo que respecta a los usuarios de las clases, simplemente sucede que (actualmente) se implementará usándolo.

+0

Explicación impresionante en frases tan pequeñas +1 –

17

herencia público significa que todo el mundo sabe que el derivado se deriva de la Base.

herencia de Protección significa que sólo derivada, amigos de derivadas y clases derivadas de conocimientos Derivado la derivada se deriva de la Base. *

herencia privada significa que sólo derivan y amigos de conocimientos derivada que deriva se derivan de Base .

Dado que ha utilizado la herencia privada, su función main() no tiene ninguna pista sobre la derivación desde la base, por lo tanto, no puede asignar el puntero.

La herencia privada se suele utilizar para cumplir con la relación "is-applied-in-terms-of". Un ejemplo podría ser que Base expone una función virtual que necesita anular y, por lo tanto, debe heredarse, pero no desea que los clientes sepan que usted tiene esa relación de herencia.

* también: la cantidad de madera sería una marmota chuck ...

+4

Tres años y medio después, y una adición a mi respuesta: en el caso de la herencia privada, nótese que ni siquiera Base sabe que Derived se deriva de Base. Es decir, 'dynamic_cast (this)' en una función miembro de Base siempre devolverá NULL si Derived hereda de Base de forma privada. Menciono esto porque me mordió recientemente al intentar herencia privada de una clase aprobada a través del patrón de plantilla curiosamente recursivo. –

Cuestiones relacionadas