sencillos resueltos relaciones que programacion poo polimorfismo orientada objetos objeto herencia entre ejercicios ejemplos ejemplo codigo clases clase abstracta c++ exception-handling virtual-inheritance

c++ - resueltos - ¿Es necesaria la herencia virtual para las excepciones?



que es un objeto en c++ (5)

Entiendo la necesidad de herencia virtual cuando uso herencia múltiple: resuelve el temido problema del diamante.

Pero, ¿y si no estoy usando herencia múltiple? ¿Hay alguna necesidad de herencia virtual en absoluto?

Me parece recordar haber oído que era importante para las excepciones (lanzar una clase derivada, capturar por referencia de clase base). Pero, ¿no deberían ser suficientes los destructores virtuales para eso?

Intenté buscar la página de referencia que una vez vi sobre esto, pero parece que no puedo encontrarla.


No, no es necesario, excepto para resolver el problema del diamante. ¡Debes estar imaginando cosas!


Probablemente estés pensando en esta guía de Boost.Exception , que copiaré aquí para completarla:

Uso de herencia virtual en tipos de excepción

Los tipos de excepción deben usar herencia virtual cuando se derivan de otros tipos de excepción. Esta idea se debe a Andrew Koenig. El uso de la herencia virtual evita problemas de ambigüedad en el manejador de excepciones:

#include <iostream> struct my_exc1 : std::exception { char const* what() const throw(); }; struct my_exc2 : std::exception { char const* what() const throw(); }; struct your_exc3 : my_exc1, my_exc2 {}; int main() { try { throw your_exc3(); } catch(std::exception const& e) {} catch(...) { std::cout << "whoops!" << std::endl; } }

El programa de arriba muestra "¡Ups!" porque la conversión a std :: exception es ambigua.

La sobrecarga introducida por la herencia virtual es siempre insignificante en el contexto del manejo de excepciones. Tenga en cuenta que las bases virtuales se inicializan directamente por el constructor del tipo derivado más (el tipo pasado a la instrucción throw, en el caso de excepciones). Sin embargo, normalmente este detalle no tiene importancia cuando se usa boost :: exception , porque habilita los tipos de excepción para que sean estructuras triviales sin miembros (no hay nada que inicializar). Consulte Tipos de excepciones como etiquetas semánticas simples .


Sí, si sus clases de excepción implican herencia múltiple.


El único costo de la herencia virtual es el vtable, que no representa un gran costo. El uso de la herencia virtual significa que, más tarde, después de que las personas hereden de varias cosas, el problema del doble diamante no hará que su fea cabeza retroceda inesperadamente. Simplemente significa que su clase será una buena clase base.


Entiendo la necesidad de herencia virtual cuando uso herencia múltiple: resuelve el temido problema del diamante.

Pero, ¿y si no estoy usando herencia múltiple?

Pregunta (principalmente retórica): ¿Cómo sabría que MI nunca se usará?

Respuesta: No puedes saber eso. (Hasta que demuestres que lo haces)

Me parece recordar haber oído que era importante para las excepciones (lanzar una clase derivada, capturar por referencia de clase base). Pero, ¿no deberían ser suficientes los destructores virtuales para eso?

Pregunta (retórica): ¿Por qué sería necesario un destructor virtual aquí?

Respuesta: No lo es.