Si no hay sobrecarga de funciones, el nombre de la función sirve como la dirección del código de función, y cuando se llama a una función, su dirección es fácil de encontrar usando su nombre. Sin embargo, con la sobrecarga de funciones, ¿cómo exactamente puede el programa encontrar la dirección de función correcta? ¿Hay una tabla oculta similar a las tablas virtuales que almacena las funciones sobrecargadas con su dirección? ¡Muchas gracias!En C++, ¿cómo se implementa típicamente la sobrecarga de funciones?
Respuesta
El compilador puede ver la llamada y hacerla coincidir con las implementaciones sobrecargadas existentes conocidas, y seleccionar la correcta. No hay necesidad de una tabla dinámica, todo es perfectamente factible estáticamente en tiempo de compilación.
Actualización: eliminado mi intento de ilustrar el concepto mostrando las funciones de nombre diferente que el compilador puede elegir.
La gente dice que esta tecniq Name Mangling. Busque esta palabra clave – SunnyShah
El cambio de nombre es solo para diferenciar entre nombres de identificadores, sobrecargados o no. El objetivo principal del cambio de nombre no es atender a la sobrecarga, sino evitar conflictos de nombres. En el caso sobrecargado, el compilador tiene que determinar qué método llamar y ahí es donde está la lógica principal. Creo que el OP quería saber si esto era una cosa de tiempo de compilación/tiempo de ejecución. –
Eso no es exacto, por lo general, el vinculador necesita calcular la dirección de la llamada. La decoración del nombre importa mucho. Sí, existe la posibilidad de omitir la solicitud de enlace si la función se encuentra en la misma unidad de traducción. Si eso realmente sucede es un detalle de implementación. –
Es, creo, logrado a través de renombrado de nombres:
las funciones que conoces como foo (int) y foo (doble) son en realidad un nombre como int_foo() y double_foo() (o similar, yo no estoy completamente seguro de la semántica particular empleada para C++). Esto significa que los símbolos de C++ suelen ser un orden de magnitud mayor que los nombres que se les da en el código.
Las funciones sobrecargadas se resuelven en tiempo de compilación. El compilador encuentra una coincidencia adecuada para el conjunto de parámetros dado y simplemente llama a la función correspondiente por su dirección (void foo(int)
y void foo()
son prácticamente dos funciones totalmente independientes; si tiene foo(4)
en su código, el compilador sabe a qué función llamar).
Si están hablando de métodos sobrecargados de la misma clase, así:
void function(int n);
void function(char *s);
...
objectInstance->function("Hello World")
Es una cosita tiempo de compilación. El compilador sabe (o en algunas situaciones, adivina mejor) en este punto a qué método llamar.
Un comentario que hice en la pregunta, repito aquí.
Las personas que sugieren el nombre de mangling están equivocadas, creo. No es como si el compilador destrozara el nombre y solo hiciera una búsqueda entre los nombres destrozados. Necesita inferir los tipos apropiados de los métodos disponibles. Una vez que lo hace, ya sabe a qué método llamar. A continuación, utiliza el nombre destrozado como el último paso. El cambio de nombre no es un requisito previo para determinar qué función sobrecargada llamar.
A la persona que dio un -1. Al menos deja un comentario. Puedo eliminar/editar la publicación si la información es incorrecta. ¡Dame la oportunidad de aprender también! –
Supongo que esa persona (no yo) rechazó porque realmente no dio una respuesta clara. En su lugar, solo dice "tiempo de compilación" y "el compilador solo sabe qué hacer", lo que de hecho es un poco inexacto. – AndiDog
Bueno, el cambio de nombre es inexacto, IMO. Lo mejor que podemos decir es que el "compilador sabe". Cada compilador puede tener su propia implementación. –
La firma de función se compone del nombre de función + parámetro (s) tipo (s)
Todo se hace en tiempo de compilación. El compilador de C++ en realidad modifica los nombres de las funciones que le des internamente, de manera que una función como
int foo(int a, float b, char c)
internamente consigue un nombre equivalente a
func_foo_int_float_char()
(el símbolo real es generalmente una cierta jerigonza como [email protected]@@[email protected]
).
Como puede ver, el nombre se decora según el número exacto y los tipos de parámetros pasados.Entonces, cuando llamas a una función, es fácil para el compilador mirar los parámetros que estás pasando, decorar el nombre de la función con ellos y crear el símbolo correcto. Por ejemplo,
int a, b; float f; char c;
foo(a,f,c) ; // compiler looks for an internal symbol called func_foo_int_float_char
foo(a,b,c) ; // compiler looks for a symbol called func_foo_int_int_char
De nuevo, todo se hace completamente en tiempo de compilación.
Incluso si no hay una sobrecarga de función, los compiladores normalmente modifican la función y los nombres de las variables. Se llama name mangling. Sucede tanto en C como en C++. El nombre de la función puede decorarse notablemente mediante (1) convención de llamadas, (2) función de sobrecarga de C++, (3) función de miembro de clase.
GNU binutil c++filt
puede Undecorate este nombre revuelto, y en Windows, hay UnDecorateSymbolName
compiladores de C++ usar el nombre mangling (nombre diferente para cada uno de sobrecarga) para distinguir entre las funciones en el archivo objeto. Por ejemplo
int test(int a){}
int test(float a,float b){}
int test(double a){}
int testbam(double a){}
produciría los nombres de símbolos __Z4testi
, __Z4testff
, __Z4testd
, __Z7testbamd
. Este nombre de manipulación es altamente dependiente del compilador (lamentablemente) y una de las muchas razones por las que a menudo se prefiere C sobre C++.
Al llamar a la función test
, el compilador coincide con los tipos de argumento y el número de argumentos dados para cada sobrecarga de función. Los prototipos de funciones se usan para descubrir cuál debería llamarse.
- 1. sobrecarga de funciones en C++
- 2. sobrecarga de funciones en C
- 3. ANSI C y la sobrecarga de funciones
- 4. ¿Por qué se agregó la sobrecarga de funciones a C++?
- 5. F #: funciones de sobrecarga
- 6. ¿Es posible la sobrecarga de funciones en el objetivo C?
- 7. ¿Cómo se implementa std :: tuple?
- 8. ¿Cómo se implementa una clase en C?
- 9. sobrecarga de funciones en OCaml
- 10. Sobrecarga de la herencia de C++ sin funciones virtuales
- 11. Valores predeterminados en argumentos en funciones C y sobrecarga de funciones en C
- 12. ¿Cómo se implementa la memoria de solo lectura en C?
- 13. ¿Cómo se implementa "const"?
- 14. ¿Cómo se implementa la interfaz IDynamicObject de C# 4?
- 15. ¿Cómo se implementa la herencia múltiple de C++?
- 16. sobrecarga de funciones Firmas Haskell
- 17. sobrecarga de operadores en C
- 18. ¿Cómo se implementa la referencia internamente?
- 19. ¿Cómo se implementa la autenticación en servicestack.net
- 20. Cómo se implementa la esteganografía en php
- 21. sobrecarga de funciones con parámetros const
- 22. ¿Cómo se implementa la paginación en PHP?
- 23. sobrecarga de funciones en Python: Falta
- 24. ¿C soporta sobrecarga de C?
- 25. ¿Cómo se implementa ** en Python?
- 26. ¿Cómo se implementa la función de JVM persistentes en cake?
- 27. La sobrecarga de Python funciones matemáticas utilizando Cython
- 28. Propiedades de sobrecarga en C#
- 29. ¿Cómo se implementa `let` en Clojure y cuál es su sobrecarga?
- 30. ¿Cómo se implementa la virtualización de aplicaciones?
Las personas que sugieren el nombre de manipulación están equivocadas, creo. No es como si el compilador destrozara el nombre y solo hiciera una búsqueda entre los nombres destrozados. Necesita inferir los tipos apropiados de los métodos disponibles. Una vez que lo hace, ya sabe a qué método llamar. Luego usa el nombre destrozado como el _último paso. El cambio de nombre no es un requisito previo para determinar qué función sobrecargada llamar. –
¿Tal vez este comentario debería ir en una de las respuestas equivocadas a las que te refieres? – Manuel
Hay demasiados, así que lo dejé aquí. –