Estoy aprendiendo cómo cargar DLL de forma dinámica, pero lo que no entiendo es esta línea
typedef void (*FunctionFunc)();
Tengo algunas preguntas. Si alguien puede contestarle, estaría agradecido.
- ¿Por qué se
typedef
usa? - La sintaxis parece extraña; ¿después de
void
que no debería haber un nombre de función o algo así? Parece una función anónima. - ¿Se ha creado un puntero de función para almacenar la dirección de memoria de una función?
Entonces estoy confundido en este momento; ¿Puedes aclararme las cosas?
using FunctionFunc = void (*)();
se puede utilizar en su lugar. Es un poco más claro que solo está declarando un nombre para un tipo (puntero para funcionar)using FunctionFunc = void(void);
*
es un poco más explícita.Respuestas:
typedef
es una construcción de lenguaje que asocia un nombre a un tipo.Lo usa de la misma manera que usaría el tipo original, por ejemplo
usándolos como
Como puede ver, podría reemplazar el nombre typedefed con su definición dada anteriormente.
La dificultad radica en el puntero a las funciones de sintaxis y legibilidad en C y C ++, y
typedef
puede mejorar la legibilidad de tales declaraciones. Sin embargo, la sintaxis es apropiada, ya que las funciones, a diferencia de otros tipos más simples, pueden tener un valor de retorno y parámetros, por lo tanto, la declaración a veces larga y compleja de un puntero para funcionar.La legibilidad puede comenzar a ser realmente complicada con punteros a matrices de funciones y algunos otros sabores aún más indirectos.
Para contestar tus tres preguntas
¿Por qué se usa typedef? Para facilitar la lectura del código, especialmente para punteros a funciones o nombres de estructura.
La sintaxis parece extraña (en el puntero a la declaración de la función) Esa sintaxis no es obvia de leer, al menos al comenzar. Usar una
typedef
declaración en su lugar facilita la lectura¿Se ha creado un puntero de función para almacenar la dirección de memoria de una función? Sí, un puntero de función almacena la dirección de una función. Esto no tiene nada que ver con la
typedef
construcción que solo facilita la escritura / lectura de un programa; el compilador solo expande la definición typedef antes de compilar el código real.Ejemplo:
fuente
typedef type alias
pero con los punteros de función allí sólo parece ser de 2 argumentos,typedef type
. ¿El alias está predeterminado en el nombre especificado en el argumento de tipo?square
y&square
(y, de hecho,*square
y**square
) todos se refieren al mismo puntero de función.typedef int newname
, te estás convirtiendonewname
en un alias paraint
. Contypedef int (*func)(int)
, se está convirtiendofunc
en un alias paraint (*)(int)
: un puntero para funcionar tomando unint
argumento y devolviendo unint
valor.int (*func)(int)
, entiendo que func es un alias, solo un poco confundido porque el alias está enredado con el tipo. Pasando portypedef int INT
un ejemplo, sería más fácil si el puntero de la función typedef fuera de formatypedef int(*function)(int) FUNC_1
. De esa manera, puedo ver el tipo y el alias en dos tokens separados en lugar de combinarlos en uno.typedef
se usa para los tipos de alias; en este caso que estés aliasingFunctionFunc
avoid(*)()
.De hecho, la sintaxis parece extraña, mira esto:
No, esto simplemente le dice al compilador que el
FunctionFunc
tipo será un puntero de función, no define uno, como este:fuente
typedef
no no declarar un nuevo tipo. usted puede tener muchostypedef
nombres -definida del mismo tipo, y ellos son no distinta (por ejemplo WRT. sobrecarga de funciones). hay algunas circunstancias en las que, con respecto a cómo puede usar el nombre, untypedef
nombre definido no es exactamente equivalente a lo que se define, pero lostypedef
nombres múltiples definidos para el mismo son equivalentes.Sin la
typedef
palabra, en C ++ la declaración declararía una variableFunctionFunc
de tipo puntero para funcionar sin argumentos, regresandovoid
.En
typedef
cambio, se defineFunctionFunc
como un nombre para ese tipo.fuente
Si usted puede utilizar C ++ 11 es posible que desee utilizar
std::function
yusing
palabra clave.fuente
using
palabra clave C ++ 11 seríatypedef std::function<void(int, std::string)> FunctionFunc;
, en caso de que alguien quiera otro contenedor alrededor de las funciones sin C ++ 11fuente
typedef (*double) p
, ¿es '&' opcional?typedef double* p
para definir un puntero a un doble. Si desea llenar elp
puntero desde una variable primitiva, deberá usar '&'. Una nota al margen, nosotros * <nombre del puntero> para desreferenciar un puntero. Se*
utiliza en el puntero de función para desreferenciar el puntero (nombre de la función) e ir al bloque de memoria donde se encuentran las instrucciones de la función.Para el caso general de la sintaxis se puede ver en el anexo A de la norma ANSI C .
En el formulario Backus-Naur desde allí, puede ver que
typedef
tiene el tipostorage-class-specifier
.En el tipo
declaration-specifiers
, puede ver que puede mezclar muchos tipos de especificador, cuyo orden no importa.Por ejemplo, es correcto decir,
para definir el tipo
a
como un alias paralong long
. Por lo tanto, para comprender la definición de tipo en el uso exhaustivo, debe consultar alguna forma de backus-naur que defina la sintaxis (hay muchas gramáticas correctas para ANSI C, no solo la de ISO).Cuando utiliza typedef para definir un alias para un tipo de función, debe colocar el alias en el mismo lugar donde coloca el identificador de la función. En su caso, defina el tipo
FunctionFunc
como un alias para que funcione un puntero cuya verificación de tipo esté deshabilitada en la llamada y no devuelva nada.fuente