2011-07-21 17 views
5

Escribo una gran clase base abstracta con 30 métodos puramente virtuales *.Grandes clases base abstractas

Encontrar todas las funciones para implementar en una clase base en las clases de implementación es un poco tedioso, sobre todo porque MSVC++ no lo hace te dice qué función usted no pudo poner en práctica con el error del compilador "No se puede construir la clase abstracta"

Entonces, me pregunto si mi gran clase base abstracta es una mala idea, o debería dividirla en varias interfaces, o si hay una advertencia del compilador que puedo activar que me dirá cuál método fallé para proporcionar una implementación para ... o es solo una parte de la codificación con clases abstractas y debería acostumbrarme a eso.

* Lo que hace es proporcionar una capa de funcionalidad común entre unos subsistemas de representación diferentes.

+2

Mi MSVC no me dice qué funciones son abstractas. – Puppy

+1

Si puede dividir la interfaz para borrar componentes, hágalo. No pretendo tener una buena razón racional para esto, pero creo que obviamente es algo bueno de hacer. –

Respuesta

4

No hay una respuesta correcta obvia a esta pregunta. Decidir si factorizar aparte la clase base en múltiples clases base abstractas probablemente sea una decisión que tome en función de si la clase base lógicamente representa varios conceptos diferentes, en lugar de mensajes de error del compilador deficientes. Si la única razón por la que haría esto es por los mensajes de error del compilador, es posible que desee comprobar y ver si puede actualizar el compilador o si hay alguna otra razón para hacerlo. La mayoría de los compiladores modernos deberían proporcionar errores muy agradables y detallados al respecto.

La división de la interfaz en piezas puede ser una buena idea si su diseño sugiere que realmente podría querer tener múltiples clases diferentes que implementen solo piezas pequeñas de la clase base. Si espera hacer esto, puede ser ventajoso separar la interfaz. Sin embargo, verá una complejidad añadida a partir de esto. Por ejemplo, si tiene un puntero de un tipo de interfaz para un objeto que implementa múltiples interfaces, puede que tenga que hacer algún tipo de conversión cruzada para obtener el tipo correcto, o puede que tenga que introducir una nueva clase abstracta que represente algo que hereda de todos los diferentes tipos de interfaz. La herencia múltiple con clases de interfaz también puede provocar algunas colisiones de nombres, aunque esto normalmente no es un problema si las interfaces están diseñadas correctamente.

En resumen, te sugiero que no hagas esto por el motivo del error del compilador, pero si crees que es una buena decisión de diseño, entonces, por supuesto, hazlo. Los compiladores son lo suficientemente buenos en estos días que rara vez (pero no nunca) necesita construir su diseño a su alrededor.

4

Las clases de interfaz en mi opinión son inherentemente malas, sin embargo, la pregunta planteada hace que esta aplicación en particular suene sospechosa.

Si tiene clases que se derivan de esta interfaz, y no está claro exactamente qué funciones necesita anular, eso parece indicar que todas esas funciones pueden no ser necesarias.

Cuando cree una clase base abstracta, la cantidad de métodos virtuales puros no es importante (para mí), pero debe quedar claro por qué cada clase que deriva de esta interfaz debe implementar cada función virtual pura. Si se encuentra pensando "¿Por qué tengo que implementar esta función?", Puede ser apropiado dividir la clase abstracta en varias interfaces distintas.

+2

El último párrafo realmente llega a las entrañas del problema aquí. –

0

De todos modos una clase tan grande es un desastre, clase de Dios antipatern. Usar agregación/composición para dividir una clase y echar un vistazo a los principios de desarrollo SÓLIDOS, parece que 30 métodos para una sola clase no siguen el principio de responsabilidad única, al menos ... así que deseé reconsiderar un diseño de clase. ¡Buena suerte!

0

Normalmente, justo después del error "No se puede crear una instancia de clase abstracta" (que se lanza en la línea que se llamó), si copió y pegó la interfaz en la clase antes de escribir las implementaciones, obtendrá un error de enlazador "Error externo no resuelto" que apunta al método que olvidaste implementar.