AFAIK, el término despacho significa solo una resolución de método y una llamada. No importa si es estático o dinámico. Vi que muchas personas están usando un término como despacho estático y despacho dinámico .
Lo que me confunde es que también hay algunas descripciones misteriosas. Estaba tratando de entender qué es el envío múltiple , y parece que solo selecciono un subprograma por tipos de parámetros . Si lo entendí correctamente, puede haber un despacho múltiple estático y un despacho múltiple dinámico , y podemos decir que C ++ está proporcionando despacho múltiple a través de funciones gratuitas.
Pero, el artículo de Wikipedia sobre despacho múltiple dice que C ++ no tiene despacho múltiple porque no tiene una resolución dinámica de función por múltiples parámetros. Y realmente no obtengo una diferencia conceptual entre el ejemplo de Common Lisp y la función sobrecargada de C ++. Porque no puedo encontrar ninguna diferencia conceptual a menos que el término despacho múltiple implique despacho dinámico . Y me di cuenta de que estoy confundiendo lo que realmente es el despacho
También verifiqué la entrada de control de calidad Despacho múltiple frente a sobrecarga de funciones , y parece que la respuesta es que el término despacho es básicamente dinámico . Eso también me confunde.
¿Cuál es el significado correcto del término despacho ? ¿Implica una resolución dinámica ? ¿Este término está bien definido o es simplemente convencional? ¿Qué me estoy perdiendo?
fuente
Respuestas:
Los términos significan lo siguiente:
despacho estático = el orden de despacho se define en tiempo de compilación . Simplemente significa que cualquier llamada a función / método dice
foo()
ox.foo()
invocará siempre la misma función; esto se establece una vez y luego permanece de esa manera. Esto implica que el compilador puede determinar el tipo dex
en tiempo de compilación.despacho dinámico = el pedido de despacho se resuelve en tiempo de ejecución . Esto significa que el compilador construye una tabla de búsqueda de todas las funciones / métodos y determina a cuál llamar realmente en tiempo de ejecución. Digamos que hay clases A y B, que implementan la interfaz X con el método
X.bar()
. En tiempo de ejecución,y
se examina y se basa en su clase realA.bar()
oB.bar()
se llama.despacho dinámico múltiple = el orden de despacho depende del nombre de función / método + tipos de argumento (= también conocido como firma ), y la implementación real que se llama se determina dinámicamente en tiempo de ejecución. Digamos que la clase A implementa métodos
A.fooBar(int)
yA.fooBar(char *)
, y hay una llamada aa.fooBar(x)
su programa. Tanto en tiempo de ejecucióna
yx
se examinan y el método real de llamada se determina con base en el tipo dex
.Vea Wikipedia para más información sobre despacho dinámico y despacho dinámico múltiple .
fuente
Mi consejo aquí es: no pienses demasiado en este. Despacho simplemente significa enviar. Enviar un evento a un oyente, enviar una interrupción a un controlador, enviar un mensaje a un receptor, enviar una llamada a un procedimiento o función: todos los aspectos del mismo concepto básico. Envíe los datos al código que lo manejará. Resolución significa elegir entre los destinos disponibles, y es solo una parte del envío.
En términos de código, el envío comienza con algún tipo de paquete de información y algo que indica dónde debe enviarse, y finaliza cuando el paquete se ha enviado (enviado). Todos los idiomas tienen algún tipo de mecanismo de despacho incorporado, pero muchos implementan esquemas de resolución y despacho para satisfacer un propósito único. El manejo de interrupciones y el procesamiento de mensajes de Windows son ejemplos que vienen a la mente.
C ++ puede usar resolución estática o dinámica, pero si elige entre funciones basadas en tipos de argumentos, solo puede hacerlo en tiempo de compilación. Smalltalk / Objective C y Ruby resuelven despachos en tiempo de ejecución, al igual que muchos lenguajes dinámicos.
Despacho único significa que se considera un único argumento como el receptor y determina qué método se llama. El método está típicamente en la clase para ese objeto receptor, y la firma del método se convierte en un desplazamiento en una tabla de despacho (vtable) en esa clase. El objeto privilegiado en C ++ es el anterior al punto, que se convierte en el puntero 'this'.
El envío múltiple significa que no hay un receptor con privilegios, pero generalmente es una operación de coincidencia de patrones en todos los tipos de argumentos. El sistema de objetos Common Lisp utiliza este enfoque. Ver https://en.wikipedia.org/wiki/Multiple_dispatch .
En C ++ con operadores sobrecargados, A + B y B + A deben despacharse a diferentes métodos. En CLOS pueden ser lo mismo.
Probablemente prefiera el término MultiMethods, ya que es una resolución de múltiples factores en lugar de un despacho múltiple per se. Ver http://c2.com/cgi/wiki?MultiMethods . También http://www.codeproject.com/Articles/242749/Multiple-dispatch-and-double-dispatch .
fuente
C ++ no tiene despacho múltiple (dinámico). Considera lo siguiente:
La salida de lo anterior es
Dentro
process(Foo& foo, const Bar& bar)
, C ++ usa el despacho dinámico en el argumentofoo
en la declaraciónfoo.dispatch(bar)
. Las líneas de salida tercera y cuarta muestran este despacho dinámico de estilo C ++ en acción. La cuarta línea de salida demuestra que C ++ no tiene despacho múltiple. Si lo hiciera, esa cuarta línea de salida sería la misma que la última.Esa linea final? Eso es despacho estático. El compilador sabe en tiempo de compilación exactamente qué función debe llamarse. Esta última llamada no pasa por la tabla virtual.
fuente