2009-03-13 11 views
0

Ich bin mir nicht sicher, ob die Frage bereits angesprochen ist. Ich habe die Stack-Overflow-Funktion überprüft und diesen Zweifel bekommen.Was bedeutet `vcall '{0, {flat}} im folgenden Beispiel?

Hier können Sie den Code überprüfen Sie zuerst:

#include <string> 
#include <map> 
#include <iostream.h> 

class MyClass 
{ 
public: 

    virtual int Func() 
    { 
     return 0; 
    } 

    int Func2() 
    { 
     return 0; 
    } 

}; 

class MyClass2 : public MyClass 
{ 
public: 

    int Func() 
    { 
     return 1; 
    } 

    int Func2() 
    { 
     return 1; 
    } 

}; 

class Processor 
{ 
private: 
     typedef int (MyClass::*MemFuncGetter)(); 
     static std::map<std::string, MemFuncGetter> descrToFuncMap; 

public: 
     static void Initialize(); 
     void Process(MyClass* m, const std::string&); 

}; 

std::map<std::string, Processor::MemFuncGetter> Processor::descrToFuncMap; 
void Processor::Initialize() 
{ 

    descrToFuncMap["Func"]=&MyClass::Func; 
    descrToFuncMap["Func2"]=&MyClass::Func2; 
}; 

void Processor::Process(MyClass* ms, const std::string& key) 
{ 
    std::map<std::string, MemFuncGetter>::iterator found = descrToFuncMap.find(key); 
    if(found != descrToFuncMap.end()) 
    { 
     MemFuncGetter memFunc = found->second; 
     int dResult = (ms->*memFunc)(); 
     cout << "Result is : "<< dResult <<endl; 
     } 
} 


int main(int argc, char* argv[]) 
{ 
    Processor::Initialize(); 
    Processor p; 

    MyClass *pMC2 = new MyClass2; 
    p.Process(pMC2, "Func"); 
    p.Process(pMC2, "Func2"); 

    delete pMC2; 
    pMC2 = NULL; 

    return 0; 
} 

In diesem Beispiel wird das Ergebnis wie erwartet:

Result is : 1 
Result is : 0 

Aber wenn ich gedebuggt VC 6 Debugger und den Wert von memFunc beobachtet in Processor :: Process und folgende Werte gefunden:

In p.Process (pMC2, "Func"); Anruf

memFunc 0x004011bd [thunk]:`vcall'{0,{flat}}' 

In p.Process (pMC2, "Func2"); rufen

memFunc 0x0040118b MyClass::Func2(void) 

ich nicht und flach in thunk verstand "[thunk]:` Vcall '{0, {flach}}"? Kann mir jemand helfen, die Interna hier zu verstehen?

Antwort

3

Es ist eine ziemlich ausführliche Erklärung dessen, was thunk bedeutet über auf WikiPedia

http://en.wikipedia.org/wiki/Thunk

Der Kern thunk wird, ist der Mechanismus, mit dem die C++ virtuelle Tabelle zur Laufzeit zugegriffen wird. Es ist eingerichtet, die entsprechende virtuelle Funktion für den Laufzeittyp des Objekts aufzurufen.

Was der vcall {0, {flat}} bedeutet, bin ich nicht 100% sicher. Meine Rate ist, dass es die Werte meldet, mit denen der Thunk auf die Methode zugreift.

  • 0: Offset in der VTable
  • {flach}: Vererbungshierarchie ist flach nicht mehrere
+0

Ich glaube nicht, dass '{flat}' die Vererbungshierarchie angibt. Ich habe ein paar mehrfache Vererbungstests gemacht und es ist immer '{flat}'. Nicht sicher, wofür es ist. –

1

Die unterschiedlichen Schreibweisen, da Mitglied Funktionszeiger müssen verschiedene virtuelle handhaben zu können und nicht virtuelle Member-Funktionen (obwohl keine statischen Member-Funktionen) und es muss in der Lage sein, Member-Funktionen, die zu der Klasse gehören, über verschiedene Formen der Vererbung (öffentlich, privat und/oder virtuell) zu handhaben.

Der beste Artikel, den ich kenne, der erklärt, wie Elementfunktionszeiger arbeiten, ist Doug Clugstons "Member Function Pointers and the Fastest Possible C++ Delegates" on The Code Project.

Sie würden wahrscheinlich erraten, dass ein "Mitgliedsfunktionszeiger" wie ein normaler Funktionszeiger nur einen Codezeiger enthält. Du würdest dich irren. Bei fast allen Compilern ist ein Mitgliedsfunktionszeiger größer als ein Funktionszeiger. Am seltsamsten ist, dass in Visual C++ ein Mitgliedsfunktionszeiger 4, 8, 12 oder 16 Byte lang sein kann, abhängig von der Art der Klasse, der er zugeordnet ist, und abhängig davon, welche Compilereinstellungen verwendet werden! Mitgliedsfunktionszeiger sind komplexer als Sie vielleicht erwarten.

Es ist nicht leicht zu lesen, aber es lohnt sich - die Informationen sind schwer irgendwo anders zu finden.dass Artikel ein gutes Buch geben könnte Ihnen einen Einblick in das, was der Debugger wirklich sagen, wenn es Sie Dinge wie

zeigt
[thunk]:`vcall'{0,{flat}}' 

JaredPar's answer ist wahrscheinlich so ziemlich auf die Marke - Clugstons' Artikel gibt Ihnen den Rest der Geschichte.