vtable: zugrunde liegender Algorithmus

8

Mein Verständnis von vtables ist, dass es, wenn ich eine Klasse Cat mit einer virtuellen Funktion speak () mit den Unterklassen Lion und HouseCat habe, eine vtable gibt, die speak () der korrekten Implementierung für jede Subklasse zuordnet. Also ein Anruf

%Vor%

Kompiliert zu

%Vor%

Das heißt, ein Nachschlagen in der vtable-Position 0 und ein Aufruf des Funktionszeigers in dieser Position.

Meine Frage ist: Was passiert bei Mehrfachvererbung?

Lass uns eine Klasse Pet hinzufügen. Pet hat virtuelle Funktionen speak () und iss (). HouseCat erweitert Pet, Lion hingegen nicht. Jetzt muss ich sicherstellen, dass

%Vor%

Kompiliert als

%Vor%

Das ist vtable [0] muss sprechen () sein. Pet.eat muss Slot 1 sein. Das liegt daran, dass cat.speak () auf Slot 0 in der vtable zugreifen muss, und wenn für einen HouseCat Slot 0 essen ist, wird das furchtbar schief gehen.

Wie stellt der Compiler sicher, dass die vtable-Indizes zusammenpassen?

    
Alex 17.04.2017, 11:02
quelle

1 Antwort

1

Nichts wird durch die Spezifikation festgelegt, aber normalerweise würde der Compiler eine vtable für jede unmittelbare nicht-virtuelle Basisklasse plus eine vtable für die abgeleitete Klasse generieren - und dann die vtable für die erste Basisklasse und die vtable für die abgeleitete Klasse Die Klasse wird zusammengeführt.

Konkreter gesagt, was der Compiler beim Aufbau der Klassen generiert:

  • Katze

    %Vor%
  • Haustier

    %Vor%
  • Löwe

    %Vor%
  • Hauskatze

    %Vor%

Was der Compiler bei Aufrufen / Umwandlungen generiert (Variablenname ist der Name des statischen Typs):

  • %Code%
    • cat.speak() - gültig für Cat, Lion und den "Cat" -Teil von HouseCat
  • %Code%
    • obj[0][0]() - gültig für Pet und den "Pet" -Teil von HouseCat
  • %Code%
    • pet.eat() - gültig für Lion
  • %Code%
    • obj[0][0]() - gültig für den "Cat" Teil von HouseCat
  • %Code%
    • lion.speak() - gültig für den "Pet" Teil von HouseCat
  • %Code%
    • obj[0][0]()
  • %Code%
    • houseCat.speak()

Ich schätze, das Wichtigste, was Sie verwirrt hat, ist, dass (1) mehrere VTables möglich sind und (2) Upcasts möglicherweise eine andere Adresse zurückgeben.

    
Oak 03.05.2017, 04:18
quelle