Come mai puntatore ad una funzione essere convocata senza dereferenziazione?
-
09-09-2019 - |
Domanda
Ho una dichiarazione typedef strano in un programma C ++, generato da Py ++.
double radius(int); // function to be wrapped
typedef double (*radius_function_type)(int);
bp::def("radius", radius_function_type(&radius)); // bp::def is a function for wrapping
Quello che ho capito finora è che quanto sopra typedef statemnt non è del tipo, la maggior parte di noi hanno familiarità con,
typedef complex_type simple_alias;
Piuttosto è un modo per dichiarare puntatore ad una funzione che prende int come argomento e restituisce doppio (uguale al prototipo). Quindi la mia domanda ora è che, come mai puntatore ad una funzione (senza dereferenziando) in denominato con l'indirizzo di una funzione come argomento? Anche questo non corrisponde con il prototipo. Qualcuno per favore spiegare!
Soluzione
La tua domanda è confusa. State chiedendo quello che fa:
radius_function_type(&radius)"
Questa è solo una C ++ typecast, un po 'come:
radius (int (42));
ma dato raggio è già di tipo radius_function_type allora si può altrettanto facilmente fare:
bp::def("radius", radius);
ma come questo codice è generato da Py ++, è probabilmente essere molto attenti con l'uscita.
Altri suggerimenti
Non dichiarare una variabile puntatore a funzione, ma un puntatore a funzione typedef chiamata radius_function_type
. radius_function_type(&radius)
è solo una (ridondante) Cast per il puntatore di funzione stessa. (Il &
unario operatore di indirizzo è ridondante,. Per una funzione, radius
e &radius
sono la stessa cosa)
A livello basso, chiamando una funzione è solo mettendo argomenti qualche secondo sottostante convenzione di chiamata (solitamente in pila) e poi saltare ad un indirizzo di memoria. Quindi il compilatore può chiamare una funzione con solo un puntatore se si conosce il tipo di puntatore a funzione (firma di funzione) e il valore del puntatore stesso.
Beh ... è un po 'simile a come gli array sono legati ai puntatori, in C e C ++. Il nome di una funzione è fondamentalmente un puntatore, anche. Visto da questa prospettiva, non è troppo sorprendente che data una definizione:
int foo(int a, int b)
{
return a + b;
}
È possibile effettuare la chiamata sia direttamente, attraverso il puntatore che è il nome della funzione:
foo(1, 2);
o memorizzando tale valore in una variabile separata, che deve essere dichiarato come un puntatore:
int (*pointer)(int, int) = foo;
pointer(1, 2);
In questo caso, siamo in grado di chiamare attraverso la variabile puntatore direttamente, e non c'è nemmeno bisogno di esplicitamente "prendere l'indirizzo di" funzione scrivendo &foo
.
Dereferencing (in modo di pensare) puntatore di una funzione significa:. Accesso ad una memoria di codice come sarebbe una memoria dati
puntatore a funzione non è supponiamo di essere dereferenziati in quel modo. Invece, si chiama.
Vorrei usare un nome "dereference" fianco a fianco con "chiamata". E 'OK.
In ogni caso: C è stato progettato in modo tale che sia identificativo nome della funzione così come puntatore di funzione di holding variabile significano la stessa: l'indirizzo di memoria di codice. E permette di passare a quella della memoria utilizzando call () sintassi sia su un identificatore o variabile.
puntatore a funzione è fondamentalmente l'indirizzo della funzione che deve essere invocato. Per chiamare la funzione puntata da un puntatore a funzione, si considera il puntatore a funzione come se fosse il nome della funzione che si desidera chiamare. L'atto di chiamare esso si esegue la risoluzione del riferimento; non v'è alcuna necessità di risolvere il riferimento esplicito.
Funzione sintassi puntatore può apparire come puntatori (con & e *), o che può essere omessa pure. Come @unwind già ha sottolineato che è simile a come gli array vengono trattati in cui nuda matrice è simile al puntatore e, opzionalmente, è possibile anteporre la matrice con e per ottenere l'indirizzo.