2008-08-28 10 views

Respuesta

13

Las personas aquí parecen confundir la herencia de clase protegida y los métodos protegidos.

FWIW, nunca he visto a nadie usar la herencia de clase protegida, y si no recuerdo mal, creo que Stroustrup incluso consideró que el nivel "protegido" era un error en C++. Hay muy poco que no puedes hacer si eliminas ese nivel de protección y solo dependes de lo público y lo privado.

+0

Sólo un comentario rápido: apellido Mr. C++ 's es BS;) –

+0

Buen Señor, lo arreglaré inmediatamente.! :) –

1

C++ FAQ Lite menciona un caso en el que el uso de la herencia privada es una solución legítima (consulte [24.3.] Which should I prefer: composition or private inheritance?). Es cuando se quiere llamar a la clase derivada de dentro de una clase base privada a través de una función virtual (en este caso derivedFunction()):

class SomeImplementationClass 
{ 
protected: 
    void service() { 
     derivedFunction(); 
    } 

    virtual void derivedFunction() = 0;  

    // virtual destructor etc 
}; 

class Derived : private SomeImplementationClass 
{ 
    void someFunction() { 
     service(); 
    } 

    virtual void derivedFunction() { 
     // ... 
    } 

    // ... 
}; 

Ahora, si quieres que se derivan de la clase derivada, y desea utilizar Base::service() desde dentro de la clase derivada (digamos que desea mover Derived::someFunction() a la clase derivada), la forma más fácil de lograr esto es cambiar la herencia privada de Base a herencia protegida.

Lo siento, no puedo pensar en un ejemplo más concreto. Personalmente, me gusta hacer pública toda la herencia a fin de evitar perder el tiempo con las discusiones "¿Debería hacer que la relación de herencia sea protegida o privada?".

+1

pero eso no es lo que preguntó el afiche, preguntó sobre la herencia protegida. Ciertamente hay casos en los que desearía una herencia privada, aunque no demasiados. –

5

Hay un caso de uso muy raro de herencia protegida. Es la que desea hacer uso de covariance:

struct base { 
    virtual ~base() {} 
    virtual base & getBase() = 0; 
}; 

struct d1 : private /* protected */ base { 
    virtual base & getBase() { 
     return this; 
    } 
}; 

struct d2 : private /* protected */ d1 { 
    virtual d1 & getBase() { 
     return this; 
    } 
}; 

El fragmento anterior trató de ocultar su clase base, y proporcionar la visibilidad controlada de bases y sus funciones, por el motivo que sea, al proporcionar una función "getBase".

Sin embargo, fallará en la estructura d2, ya que d2 no sabe que d1 se deriva de base. Por lo tanto, covariance no funcionará. Una forma de salir de esto es derivarlos protegidos, para que la herencia sea visible en d2.

Un ejemplo similar de uso es cuando deriva de std::ostream, pero no desea que personas aleatorias escriban en su transmisión. Puede proporcionar una función virtual getStream que devuelva std::ostream&. Esa función podría preparar un poco el flujo para la siguiente operación. Por ejemplo poniendo ciertos manipuladores en

std::ostream& d2::getStream() { 
    this->width(10); 
    return *this; 
} 

logger.getStream() << "we are padded"; 
Cuestiones relacionadas