¿Cuál es el mejor diseño para la implementación de devolución de llamada en C ++?

7

Tengo una clase "Padre". La clase "padre" crea un objeto de la clase "hijo" en mi módulo CPP. El caso de uso es "Child" tiene que solicitar cierta información a "Parent". Esto se puede hacer de varias maneras y puedo pensar en los siguientes diseños.

1) Almacene el puntero del objeto / referencia de "Padre" en "Niño" y deje que "Niño" llame a algún método público de "Padre".

2) "Child" expone una API para registrar devoluciones de llamada. "Padre" registra una función estática con el puntero "este" como identificador de devolución de llamada. Cuando "Niño" quiere solicitar información, llamará a la función de devolución de llamada registrada con el identificador de devolución de llamada como uno de los argumentos. La función de devolución de llamada eliminará la referencia del identificador de devolución de llamada al objeto "principal" y obtendrá la información.

¿Puede alguien decirme cuál es el mejor diseño? También me gustaría saber si hay algún diseño estándar para este tipo de problema?

    
pregunta MayurK 26.07.2016 - 12:14

3 respuestas

5

Probablemente depende de qué tan apretadamente quieres que se acoplen tus objetos. Pero para un desarrollo más rápido y un código más legible, creo que el método 1 es preferible. Simplemente almacene la referencia al padre como un puntero débil (suponiendo que use C ++ moderno).

Podría hacer algún patrón en el que el padre registraría una función dentro del hijo (en este caso, prefiera los cierres y la función std :: a los punteros de función). Pero si estos dos objetos son los únicos que necesitarán compartir la información, entonces no veo ningún punto de no dar un puntero al elemento primario al objeto secundario, esto se usa con bastante frecuencia.

Finalmente, lo mejor sería tener un flujo de datos unidireccional si es posible. En lugar de hacer que el niño solicite información, haga que el padre la empuje hacia adentro. Esto hará que la interfaz sea más legible y segura (porque los padres siempre saben si es seguro enviar datos pero es posible que el niño no esté al tanto del estado de los padres). También hace que sea más fácil pasar todos los datos como valores constantes.

    
respondido por el Jozef Legény 26.07.2016 - 13:16
2

El puntero al padre es un enfoque válido. Pero es una solución muy específica que será difícil de extender.

Un mejor enfoque podría ser implementar el patrón de diseño del observador . Hay muchos ejemplos de cómo hacerlo; para comenzar con el libro de referencia GoF , o here . De hecho, esta es una forma limpia general de su opción 2 (el padre es observador, el niño es sujeto).

Si, sin embargo, prefiere el enfoque de devolución de llamada, sugiero optar por un objetos de devolución de llamada .

    
respondido por el Christophe 26.07.2016 - 18:56
1

Prueba algo orientado a objetos.

Pase al niño una interfaz que implementa el padre. Como esto crea una estructura de datos cíclica, solo tienes que liberar las cosas en el orden correcto; algo de lo que no nos preocupamos en otros idiomas ...

Es posible que el niño solo necesite acceso al padre (interfaz) en ciertos momentos conocidos, por lo que quizás pueda proporcionar eso como un parámetro a un método secundario en lugar de un parámetro al constructor.

De lo contrario, si el niño necesita responder a los cambios en el padre, considere el patrón Observer .

    
respondido por el Erik Eidt 26.07.2016 - 18:17

Lea otras preguntas en las etiquetas