Explicação dos ponteiros de função
Eu tenho um problema ao entender algumas sintaxes do C ++ combinadas com ponteiros de função e declarações de função, ou seja:
Normalmente, quando queremos declarar um tipo de função, criamos algo como:
typedef void(*functionPtr)(int);
e isso é bom para mim. A partir de agora functionPtr é um tipo, que representa um ponteiro para a função, que retorna nulo e aceita int por um valor como argumento.
Podemos usá-lo da seguinte maneira:
typedef void(*functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
E nós temos5
impresso em uma tela.
temos ponteiro para funcionarfun
, atribuímos um ponteiro existente para funcionar -function
e executamos essa função por um ponteiro. Legal.
Agora, como eu li em alguns livros, função e ponteiro para função são tratados de alguma forma da mesma forma, de fato, após a declaração defunction()
function toda vez que dizemos function, queremos dizer função real e ponteiro para funcionar no mesmo tipo, portanto, a seguir compila e toda instrução fornece o mesmo resultado (5 impressos em uma tela):
int main() {
functionPtr fun = function;
fun(5);
(*fun)(5);
(*function)(5);
function(5);
return 0;
}
Então, agora, desde que eu possa imaginar, que os indicadores para funções e funções são praticamente os mesmos, então é algo bom para mim.
Então, porém, se o ponteiro para a função e a função real é o mesmo, então por que não posso fazer o seguinte:
typedef void(functionPtr)(int); //removed *
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
Isso me dá o seguinte erro:
prog.cpp: 12: 14: warning: a declaração de 'void fun (int)' possui 'extern' e é inicializada functionPtr fun = function;
portanto, eu entendi que, por alguma razão, o compilador agora entende que diversão éjá existente função. Então eu tentei o seguinte:
int main() {
functionPtr fun;
fun(5);
return 0;
}
E eu tenho erro de ligação. De alguma forma, eu entendo que, como o compilador agora trata a diversão como uma função já existente, devido ao fato de que a diversão não está definida em nenhum lugar, receberei um erro de vinculação. Portanto, mudei o nome da variável:
typedef void(functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr function;
function(5);
return 0;
}
Então agora funcione nas sombras principais função de nome global, entãofunction(5)
é usado a partir da declaraçãofunctionPtr function;
Funciona bem e imprime 5 na tela.
Então agora estou chocado. Por quê isso aconteceu? Outra coisa enganosa é que quando o ponteiro da função é declarado assim:
typedef void(*functionPtr)(int);
Eu posso criar uma função do tipo functionPtr da seguinte maneira:
functionPtr function(int a){
std::cout << a << std::endl;
}
enquanto que, ao declarar algo como:
typedef void(functionPtr)(int);
faz isso:
functionPtr function(int a){
std::cout << a << std::endl;
}
sendo interpretado por um compilador como função retornando função. Nesse caso, por que a declaração anterior (typedef void(functionPtr)(int);
) sabia que essa é uma função retornando nula e não função retornando functionPtr?
Alguém poderia explicar o que realmente está acontecendo para mim?
Estou usando o compilador g ++ C ++ com a opção C ++ 14 ativada.