2011-04-09 10 views
7

Al encontrar la respuesta para this query con el código de escritura de prueba, llegué a saber que la herencia privada/protegida cambia la forma en que se reciben las excepciones de varias clases, lo que fue muy sorprendente. Para encontrar la respuesta, me referí a preguntas anteriores del foro y me encontré con this similar question.¿Por qué la herencia influye en el manejo de excepciones?

Para mí es bastante obvio usar la herencia protected para una clase base con los métodos virtual. Manteniendo el estándar a un lado, quería saber ¿por qué en C++ el manejo de excepciones está restringido por herencia cuando las llamadas al método virtual no son? siguiente fragmento explica:

struct Base { virtual void printError() = 0; }; 
class Derived : protected Base { void printError() { } }; 

int main() 
{ 
try { 
    throw new Derived; 
} 
catch(Base *p) { p->printError(); } // Ideal; but not invoked 
catch(void *p) { ((Base*)p)->printError(); } // Ugly; but only way to invoke 
} 

Editar: Si tenemos en cuenta la relación privacidad como una respuesta; aceptado. ¿Pero por qué es aplicable solo para catch() recibiendo punteros base, mientras que no es aplicable para funciones que reciben punteros base?

+1

+1 buena pregunta. – Nawaz

+3

nota menor, no tiene que usar 'new' en las instrucciones' throw', solo corre el riesgo de presentar pérdidas de memoria al hacerlo. En su lugar use 'throw Derived();' y capture por referencia 'Base &'. Además, definitivamente no es obvio para mí por qué alguien usaría la herencia 'protected' si la clase base tiene métodos virtuales, creo que aquí tienes algo mal ... Y finalmente, la clase de excepciones generalmente debería heredar de' std :: exception' y sobrecarga 'char const * what() const'. –

+0

@Matthieu, gracias, pero el código anterior era solo para fines de demostración. La captura por referencia no es posible en este caso ya que no puede capturar 'void &'; Sin embargo, también prefiero la captura por referencias. Dependiendo de mi diseño, me gustaría que los métodos de clase Interface (aquí 'Base') (especialmente virtuales) no sean llamados por ninguno de sus hijos en otros espacios de nombres. – iammilind

Respuesta

10

El significado de private y la herencia protected es que nadie fuera de la jerarquía de clases o clases puede conocer la herencia. Esta es la misma manera que nadie fuera de la clase puede saber acerca de un miembro privado.
La captura de una clase derivada por su clase base reveló al receptor que la clase derivada se deriva de hecho de la clase base y es una violación de la privacidad de la herencia.

+0

+1 ¡buena respuesta con una buena explicación! – Nawaz

+0

¿Por qué hay un problema solo mientras 'catch'; cuando el mismo escenario es aplicable a una llamada de función, ¡es fácilmente aceptable! – iammilind

+0

@iammilind, mal, obtienes un error similar cuando intentas derivar una clase privada a una función con una base y un argumento. Pruébalo por ti mismo. – shoosh

5

protected herencia significa solo Derived y sus subclases "sabe" también es-a Base. main, y la declaración catch, no "sabe" esto. Este es el punto de heredar con un acceso específico.

El despacho virtual no se preocupa por esto - si tiene acceso para llamar a una función virtual, entonces el despacho virtual es usado.

En su muestra, no se puede utilizar un Derived como si fuera un Base cualquier otro lugar en el ámbito de main - así que tiene sentido que no se puede hacerlo en el catch ya sea

+0

+1 buena respuesta. : D – Nawaz

Cuestiones relacionadas