2013-06-14 9 views
7

Da alle virtuelle Funktion in C++ in V-Tabelle gespeichert ist. Die Überlagerung findet im Fall der virtuellen Funktion statt. Ich möchte fragen es gibt einen Weg, wie wir die virtuelle Funktion direkt aus der Tabelle aufrufen können und zu bestimmt, welche Funktionen V-Tabelle enthält.Aufrufen der virtuellen Funktion aus V-Tabelle

+0

Warum sollte man das tun wollen ?? Zumindest können Sie (mit einigen direkten Speicheradressierung), solange Sie wissen, über die inernals Ihres Compilers ABI. –

+0

können wir etwas tun mit V-Zeiger, der in der Klasse vorhanden ist (wenn die Klasse die virtuellen Funktionen enthält), die auf v-table.using g ++ Compiler zeigt, habe ich versucht mit dem V-Zeiger, aber es funktioniert nicht. –

Antwort

16

Nun, eigentlich können Sie. Portabilität ist mir egal, aber in VS können Sie es tun. Angenommen, dass wir 32-Bit-Code mit VS erstellen, sind die ersten 4 Bytes an der Objektadresse die vTable-Adresse. Wenn wir uns die Header-Dateien ansehen, kennen wir die Reihenfolge der Methoden in der vtable.

Beispiel:

class Base 
{ 
public: 

    virtual void printMessage() 
    { 
     std::cout << "Base::printMessage()" << std::endl; 
    } 
}; 

class Derived : public Base 
{ 
public: 

    void printMessage() 
    { 
     std::cout << "Derived::printMessage()" << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    Derived d; 

    unsigned int vtblAddress = *(unsigned int*)&d; 

    typedef void(*pFun)(void*); 

    pFun printFun = (pFun)(*(unsigned int*)(vtblAddress)); 

    printFun(&d); 

    return 0; 
} 

P. S. Ich werde nicht fragen, warum machst du es, aber hier hast du eine Option :-)

+1

das ist eigentlich ich wollte. –

+8

Unglaublich, Peter Wood, Eelke, Toro2k, Stony und Quetzalcoatl können nicht sagen, was hier gefragt wird. Wie kommt es, dass jeder Teilnehmer in diesem Thread verstanden hat, was gefragt wird? 5 "smarte" Jungs mit ziemlich niedrigem Ruf im Vergleich zu Mike Seymour und ForEveR verarschen alle anderen. Ich meine, Sie verstehen die Frage nicht, das ist in Ordnung, aber lassen Sie die anderen Leute um Himmels willen diskutieren ... – user1764961

+1

@ user1764961- yaa wirklich unglaublich Mann! –

2

Es gibt keine Garantie für den Standard, dass virtuelle Funktionen mit v-table implementiert werden. Also, nur wenn Sie sicher sind, verwenden Sie diesen Compiler v-table - Sie können benötigten Offset finden.

+1

In C++ ist es nicht notwendig, dass Compiler V-Tabelle für die Implementierung von virtuellen Funktionen verwenden wird ??? –

+0

@ user2484070 ja, es ist nicht notwendig. Die Implementierung von virtuellen Funktionen ist abhängig vom Compiler. – ForEveR

+0

@ user2484070, die Werte werden irgendwo gespeichert und irgendwie ist das sicher. Wird es ein bekannter V-Tisch oder etwas anderes sein ... ist das nicht wirklich wichtig. – user1764961

2

Portabel, nein. Die Sprache gibt nicht vor, wie der virtuelle Versand implementiert wird, sondern nur wie er sich verhält. Es wird nicht unbedingt mit einer v-Tabelle implementiert, und es gibt keine Möglichkeit, auf eine virtuelle Funktion zuzugreifen, außer sie aufzurufen.

Wenn Sie nur einen bestimmten ABI unterstützen müssen, können Sie die Implementierungsdetails zusammen mit einigen zweifelhaften Zeigermodellen verwenden, um ein Objekt auf dieselbe Weise einem Funktionszeiger zuzuordnen, wie es der virtuelle Dispatch-Mechanismus tut. Aber Sie werden außerhalb der definierten Sprache in ein nicht unterstütztes, nicht tragbares Territorium wechseln, also würde ich definitiv empfehlen, alles zu überdenken, was Sie auch tun möchten.

+1

hab es geschafft. Danke :) –

0

Ich würde nein im Allgemeinen sagen, weil die genaue Implementierung der vtable eine Plattform/Compiler spezifisch ist. Wenn Sie wissen, wie die Plattform/der Compiler die vtable und die Adresse implementiert, könnte es möglich sein, sie zu berechnen, indem Sie die Adresse einer vtable für eine bestimmte Klasse ermitteln und dann einen Offset einer virtuellen Methode hinzufügen.

Die vtable enthält alle virtuellen Methoden für die Klasse. Sie können die Anwendung zerlegen, um sie zu sehen.