2010-04-06 13 views
19

quiero preguntar acerca de puntero en C++++ puntero a funciones C, Principiante Pregunta

que tienen algún código simple:

int add(int a, int b){ 
return a+b; 
} 

int runner(int x,int y, int (*functocall)(int, int)){ 
return (*functocall)(x,y); 
} 

Ahora, supongamos que llamo esas funciones utilizando de esta manera:

cout<<runner(2,5,&add); 

o tal vez

cout<<runner(2,5,add); 

¿hay alguna diferencia? porque cuando lo intenté, el resultado es el mismo y sin error.

Muchas gracias

Respuesta

0

creo que la segunda llamada resuelve automáticamente a la primera llamada en el compilador ...

+0

¿quiere decir que la segunda llamada es la correcta? – BobAlmond

+1

no, quiero decir que el compilador resuelve cualquiera de las llamadas a un puntero de función, y es realmente una cuestión de preferencia sintáctica. –

10

función se debe enyesar implícitamente a un puntero de acuerdo a C++ estándar (4,3/1). No hay diferencia. Sin embargo, esta conversión nunca se aplica a funciones de miembros no estáticos. Para ellos, debe escribir explícitamente &.

3

No hay diferencia. Para coherencia con otras formas de obtener un puntero, puede usar &, pero el nombre en sí mismo no tendría otro significado, por lo que se supone que significa "obtener la dirección".

Es muy similar a los nombres de variables de matriz que actúan como la dirección del primer elemento de la matriz.

0

es porque no hay tal objeto (en términos de expresiones) como función , sólo hay punteros a funciones. Cuando desea pasar la función a su función, lo único que puede pasar es el puntero, por lo que el compilador hace este cast por usted

+0

Hay objetos llamados funciones (en términos de expresiones): 'add' es un objeto de este tipo, su tipo es' int (int, int) '. Sin embargo, se degradan implícitamente a sí mismos en muchos contextos. – avakar

+0

muestre el ejemplo donde la función y el puntero para funcionar como término de expresión difieren realmente – Andrey

+0

Sí, las funciones no son objetos, pero son funciones (sorpresa xD). Por ejemplo 'void f() {} void (& fr)() = f;' funciona porque f es una expresión de tipo de función y usted vincula la referencia a él, mientras que 'void (& fr)() = & f;' no trabajo porque '& f' es una expresión del tipo de puntero. Otro ejemplo: intente hacer 'sizeof (f)' y observe que falla, porque las funciones no tienen un tamaño. Como dice @avakar, el tipo de f aquí es 'void()', y el de add es 'int (int, int)' –

3

No, en este caso particular, no hay diferencia. Cualquiera de los dos le da la dirección de la función.

Tenga en cuenta, sin embargo, que en C++, obtener un puntero a una función de miembro requiere que utilice el operador '&'.

1

Tenga en cuenta que usted puede tener referencias a funciones

int runner(int x,int y, int (&functocall)(int, int)){ 
return functocall(x,y); 
} 

denomina ahora con &add no funcionará más porque intenta enlazar una referencia a un puntero de función en lugar de a una función. A veces esto brilla a través de al usar las plantillas

template<typename T> 
int runner(int x,int y, T &functocall, T otherfunc){ 
return functocall(x,y) + otherfunc(y, x); 
} 

Ahora llamándola con runner(10, 20, add, add) fallará porque T se intenta deducir tanto a un puntero de función y un tipo de función (sin descomposición a un puntero que se hace cuando se pasa a una referencia ¡parámetro!).

Cuestiones relacionadas