2008-08-02 23 views
40

Estoy trabajando en una colección de clases utilizadas para la reproducción y grabación de videos. Tengo una clase principal que actúa como la interfaz pública, con métodos como play(), stop(), pause(), record() etc ... Luego tengo clases de caballo de batalla que hacen la decodificación de video y la codificación de video.¿Debo usar clases anidadas en este caso?

Acabo de enterarme de la existencia de clases anidadas en C++, y tengo curiosidad por saber qué piensan los programadores sobre su uso. Estoy un poco cauteloso y no estoy seguro de cuáles son los beneficios/inconvenientes, pero parecen (de acuerdo con el libro que estoy leyendo) para ser utilizados en casos como el mío.

El libro sugiere que en un escenario como el mío, una buena solución sería anidar las clases de caballo de batalla dentro de la clase de interfaz, por lo que no hay archivos separados para clases que el cliente no debe usar, y para evitar cualquier posible nombrando conflictos? No sé sobre estas justificaciones. Las clases anidadas son un concepto nuevo para mí. Solo quiero ver qué piensan los programadores sobre el problema.

Respuesta

24

Sería un poco reacio a utilizar las clases anidadas aquí. ¿Qué sucede si crea una clase base abstracta para un "controlador multimedia" para manejar las cosas de back-end (workhorse), y una clase separada para el trabajo de front-end? La clase de front-end podría tomar un puntero/referencia a una clase de controlador implementada (para el tipo de medio apropiado y la situación) y realizar las operaciones abstractas en la estructura de caballo de batalla.

Mi filosofía sería seguir adelante y hacer ambas estructuras accesibles para el cliente de una manera pulida, bajo la suposición de que se usarían en tándem.

Haría referencia a algo así como QTextDocument en Qt. Proporciona una interfaz directa para el manejo de datos de metal desnudo, pero transfiere la autoridad a un objeto como un QTextEdit para realizar la manipulación.

4

Una forma de decidir si se usan o no las clases anidadas es pensar si esta clase juega o no una función de apoyo o si es parte de ella.

Si existe únicamente con el fin de ayudar a otra clase, generalmente lo hago una clase anidada. Hay un montón de advertencias al respecto, algunas de las cuales parecen contradictorias, pero todo se reduce a la experiencia y el presentimiento.

3

A veces es apropiado para ocultar las clases de implementación por parte del usuario - en estos casos es mejor ponerlos en un foo_internal.h que dentro de la definición de la clase pública . De esta forma, los lectores de tu foo.h no verán lo que preferirías que no les molestara, pero aún puedes escribir pruebas contra cada una de las implementaciones concretas de tu interfaz.

8

Utilizaría una clase anidada para crear una clase de ayuda (pequeña) que se requiere para implementar la clase principal. O por ejemplo, para definir una interfaz (una clase con métodos abstractos).

En este caso, la principal desventaja de las clases anidadas es que esto hace que sea más difícil volver a utilizarlas. Tal vez le gustaría usar su clase VideoDecoder en otro proyecto. Si lo convierte en una clase anidada de VideoPlayer, no puede hacer esto de una manera elegante.

En su lugar, coloque las otras clases en archivos .h/.cpp separados, que luego puede usar en su clase VideoPlayer. El cliente de VideoPlayer ahora solo necesita incluir el archivo que declara VideoPlayer, y aún no necesita saber cómo lo implementó.

1

Debe usar una clase interna solo cuando no pueda implementarla como una clase separada utilizando la interfaz pública de la clase externa. Las clases internas aumentan el tamaño, la complejidad y la responsabilidad de una clase, por lo que deben usarse con moderación.

Su clase codificador/decodificador suena como que mejor se ajusta a la Strategy Pattern

0

Una de las razones para evitar las clases anidadas es si alguna vez va a envolver el código con el trago (http://www.swig.org) para su uso con otros idiomas. Swig actualmente tiene problemas con las clases anidadas, por lo que interactuar con las bibliotecas que exponen cualquier clase anidada se convierte en un verdadero dolor.

3

Nos topamos con un problema con un compilador de Sun C++ semi-viejo y la visibilidad de las clases anidadas cuyo comportamiento cambió en el estándar. Esta no es una razón para no hacer su clase anidada, por supuesto, algo a tener en cuenta si planea compilar su software en muchas plataformas, incluidos compiladores antiguos.

0

Otra cosa a tener en cuenta es si alguna vez prevé implementaciones diferentes de sus funciones de trabajo (como decodificación y codificación). En ese caso, definitivamente querrías una clase base abstracta con diferentes clases concretas que implementen las funciones. Realmente no sería apropiado anidar una subclase separada para cada tipo de implementación.

4

Bueno, si utiliza punteros a sus clases de caballo de batalla en su clase de interfaz y no los expone como parámetros o tipos de retorno en sus métodos de interfaz, no necesitará incluir las definiciones para esos caballos de trabajo en su encabezado de interfaz archivo (solo en el futuro declararlos en su lugar). De esta forma, los usuarios de su interfaz no necesitarán saber sobre las clases en segundo plano.

Definitivamente no necesita anidar clases para esto. De hecho, los archivos de clase separados harán que tu código sea mucho más legible y fácil de administrar a medida que crezca tu proyecto. también lo ayudará más adelante si necesita una subclase (por ejemplo, para diferentes tipos de contenido/códec).

Aquí hay más información sobre PIMPL pattern (sección 3.1.1).

Cuestiones relacionadas