AFAIK, o termo despacho significa apenas uma resolução e chamada de método. Não importa se é estático ou dinâmico. Vi muitas pessoas usando um termo como despacho estático e despacho dinâmico .
O que me deixa confuso é que também existem algumas descrições misteriosas. Eu estava tentando entender o que é despacho múltiplo , e parece apenas selecionar um subprograma por tipos de parâmetros . Se eu entendi direito, pode haver tanto despacho múltiplo estático quanto despacho múltiplo dinâmico , e podemos dizer que o C ++ está fornecendo despacho múltiplo por meio de funções livres.
Mas, o artigo da Wikipedia sobre despacho múltiplo diz que o C ++ não tem despacho múltiplo porque não possui resolução dinâmica de função por vários parâmetros. E eu realmente não entendo diferença conceitual entre o exemplo Common Lisp e a função sobrecarregada de C ++. Porque não consigo encontrar nenhuma diferença conceitual, a menos que o termo despacho múltiplo implique despacho dinâmico . E percebi que estou confundindo o que realmente é o despacho
Também verifiquei a entrada do controle de qualidade Multiple Dispatch vs. Function Overloading , e parece que a resposta pressupõe que o termo despacho seja basicamente dinâmico . Isso também me deixa confuso.
Qual é o significado correto do termo despacho ? Isso implica resolução dinâmica ? Este termo é bem definido ou apenas convencional? o que estou perdendo?
fonte
Respostas:
Os termos significam o seguinte:
expedição estática = a ordem de expedição é definida no momento da compilação . Significa simplesmente que qualquer chamada de função / método diz
foo()
oux.foo()
sempre invocará a mesma função - isso é estabelecido uma vez e permanece assim. Isso implica que o compilador pode determinar o tipo dex
em tempo de compilação.despacho dinâmico = a ordem de despacho é resolvida no tempo de execução . Isso significa que o compilador cria uma tabela de pesquisa de todas as funções / métodos e determina qual delas realmente chamar em tempo de execução. Digamos não há classe A e B, sendo que ambos X implementar a interface com o método
X.bar()
. Em tempo de execução,y
é examinado e com base em sua classe real,A.bar()
ouB.bar()
é chamado.despacho dinâmico múltiplo = a ordem de despacho depende da função / nome do método + tipos de argumento (= assinatura ), e a implementação real que é chamada é determinada dinamicamente no tempo de execução. Diga que a classe A implementa métodos
A.fooBar(int)
eA.fooBar(char *)
, e existe uma chamadaa.fooBar(x)
no seu programa. No tempo de execução ambosa
ex
são examinadas e o método real de chamada é determinado com base no tipo dex
.Consulte a Wikipedia para obter mais informações sobre despacho dinâmico e despacho dinâmico múltiplo .
fonte
Meu conselho aqui é: não pense demais neste. Despachar significa simplesmente enviar. Despache um evento para um ouvinte, despache uma interrupção para um manipulador, despache uma mensagem para um destinatário, despache uma chamada para um procedimento ou função: todos os aspectos do mesmo conceito básico. Envie os dados para o código que os manipulará. Resolução significa escolher entre os destinos disponíveis e é apenas uma parte do envio.
Em termos de código, o despacho começa com algum tipo de pacote de informações e algo que indica para onde deve ser enviado, e termina quando o pacote é enviado (despachado). Todos os idiomas têm algum tipo de mecanismo de despacho incorporado, mas muitos implementam esquemas de resolução e despacho para atender a um propósito único. Manipulação de interrupção e processamento de mensagens do Windows são exemplos que vêm à mente.
O C ++ pode usar resolução estática ou dinâmica, mas se escolher entre funções com base em tipos de argumento, poderá fazê-lo apenas em tempo de compilação. Smalltalk / Objective C e Ruby resolvem despachos em tempo de execução, assim como muitas linguagens dinâmicas.
Despacho único significa que um único argumento é considerado o receptor e determina qual método é chamado. O método geralmente está na classe para esse objeto receptor e a assinatura do método é convertida em um deslocamento em uma tabela de expedição (vtable) nessa classe. O objeto privilegiado em C ++ é aquele antes do ponto, que se torna o ponteiro 'this'.
O envio múltiplo significa que não há receptor privilegiado, mas normalmente uma operação de correspondência de padrões em todos os tipos de argumentos. O Common Lisp Object System usa essa abordagem. Consulte https://en.wikipedia.org/wiki/Multiple_dispatch .
No C ++ com operadores sobrecarregados, A + B e B + A devem despachar para métodos diferentes. No CLOS, eles podem ser os mesmos.
Eu provavelmente prefiro o termo MultiMethods, já que é resolução multifatorial em vez de envio múltiplo em si. Consulte http://c2.com/cgi/wiki?MultiMethods . Também http://www.codeproject.com/Articles/242749/Multiple-dispatch-and-double-dispatch .
fonte
O C ++ não possui vários despachos (dinâmicos). Considere o seguinte:
A saída acima é
Dentro
process(Foo& foo, const Bar& bar)
, o C ++ usa despacho dinâmico no argumentofoo
da instruçãofoo.dispatch(bar)
. A terceira e quarta linhas de saída mostram esse despacho dinâmico no estilo C ++ em ação. A quarta linha de saída demonstra que o C ++ não tem vários despachos. Nesse caso, a quarta linha de saída seria a mesma que a anterior.Essa linha final? Isso é despacho estático. O compilador sabe em tempo de compilação exatamente qual função precisa ser chamada. Esta chamada final não passa pela tabela virtual.
fonte