2012-04-06 4 views
2

Ich weiß, dass ein Funktionszeiger die Adresse einer Funktion speichert.

wo ist die Adresse, die ein Funktionszeiger speichert

int fun(int x){ 
//return something 
} 
int (pfun*)(int)=&fun; 

int main(){ 

std::cout << &fun << "\n"; // this print out 1 
std::cout << fun << "\n" ; // this print out 1 
std::cout << &pfun << "\n"; // this print out 0x0022ff40 
std::cout << pfun << "\n" ; // this print out 1 

} 

So sind meine Fragen:
1) wenn der Spaß() hat noch nicht einmal eine Adresse wie Punkt Spaß macht Pfun kann().
2) zum Beispiel in dynamischer Bindung, wenn ich eine Zeigerfunktion zur Laufzeit verwende. Ändert der Compiler den Wert von pfun in einen echten Zeiger wie 0X ..... so dass zur Laufzeit wissen wird, welche Funktion aufgerufen werden soll, da die Namen nach der Kompilierung nicht existieren?

Antwort

5

Die Ausdrücke fun und &fun die gleiche Bedeutung haben: &fun, die auf den Wert in pfun gespeichert äquivalent ist, so ist es kein Wunder, dass die drei von ihnen die gleiche Leistung erhalten. &pfun ist die Adresse des Zeigers, der die Adresse der Variablen ist.

Nun ist die Frage, warum 1 ... na ja, ist die Antwort, dass es keine überladenen operator<< ist, die ein std::ostream und einen Funktionszeiger nimmt, so dass der Compiler versucht, die beste Übereinstimmung unter den bestehenden Überlastungen zu finden, die passiert werden bool (ein Funktionszeiger ist implizit in bool konvertierbar). Der Funktionszeiger wird nur dann in false konvertiert, wenn der Funktionszeiger Null ist, was nicht der Fall ist. Der true Wert wird schließlich als 1 gedruckt (Sie können dies überprüfen: std::cout << std::boolalpha << fun, die true drucken wird).

Wenn Sie die tatsächliche Adresse der Funktion (in diesem Prozess) erhalten möchten, können Sie den Cast auf einen void-Zeiger erzwingen und das Ergebnis ausdrucken. Dies ist möglicherweise nicht technisch korrekt, aber es gibt Ihnen eine andere Nummer als 1 ... Beachten Sie, dass der Wert in verschiedenen Läufen abweichen kann und im Grunde überhaupt keine Bedeutung hat.

+0

Wenn ich mich richtig erinnere, Casting eines Funktionszeigers auf 'void *' ist nicht erlaubt. Der Standard sagt das explizit, ich denke ... oder war es speziell Mitglied Funktionszeiger, müssen überprüfen .. –

+0

@Als: das ist der Grund für die * nicht technisch korrekt * Kommentar in der Antwort. Tatsache ist, dass IIRC in den meisten Architekturen funktioniert, der Standard garantiert dies nicht, weil einige Plattformen in der Vergangenheit unterschiedliche Zeigergrößen für Funktionen und Daten hatten, was bedeutet, dass das Umwandeln in 'void *' und zurück zum Original nicht funktionieren würde ergibt das ursprüngliche Ergebnis ... Dann wieder, wie ich bereits erwähnt habe, sogar in den Plattformen, wo es einen Wert produziert, ist es nutzlos. –

+0

Ist die explizite Erwähnung, einen Funktionszeiger auf "void *" zu schreiben, ungültig, nur für Mitgliedsfunktionszeiger anwendbar? oder sogar freistehende Funktionszeiger? –

1

operator<< hat keine geeignete Überladung zum Drucken von Funktionszeigern. Versuchen Sie es stattdessen.

#include <iostream> 

void fun() {} 

void (*pFun)() = &fun; 

int main() 
{ 
    std::cout << (void*)pFun << "\n"; 
} 
Verwandte Themen