vtable-Reihenfolge bei multipler Vererbung?

Beichtpfarrer

Erfahrenes Mitglied
Hoi,
Ich habe eine Klassenhierarchie, in der bestimmte Regeln für den vtable eingehalten werden müssen:

Code:
class BaseA{
public:
	virtual void virt1(void)=0;
	virtual void virt2(void)=0;
};


class BaseB : public BaseA{
public:
	virtual void virt1()=0;		//wird von BaseB nicht defininert
	int virt2();			//wird von BaseB definiert

	BaseB();			//BaseB besitzt sowohl Konstruktor
	virtual ~BaseB();		//als auch Destruktor
};

class BaseC{
public:
	virtual virt3()=0;
};

class Obj : public BaseB, BaseC{

//an erster stelle im vtable von Obj muss virt1 stehen (wird von Obj definiert)
//an zweiter stelle im vtable von Obj muss virt2 aus BaseB stehen (nicht von Obj definiert)

//Ab hier können sonstige Methoden/Konstruktoren in beliebiger Reihenfolge definiert sein.

};

Wie erreiche ich, dass eine Funktion, die ich nicht neu in einer abgeleiteten Klasse definieren will, an einer gewünschten Stelle im vtable steht?
Normalerweise werden die Funktionen doch in Reihenfolge der Definition im vtable aufgelistet, von Basisklassen definierte Methoden vornangehängt, oder nicht, wie dann?
Wenn ja - wie entscheidet sich, von welcher Basisklasse die Methoden zuerst eingetragen werden?
Bei Ersetzung von virtuellen Funktionen in einer Abgeleiteten Klasse, wird die Funktion an der Stelle eingetragen, an der sie auch im vtable der Basisklasse gestanden hätte?

Wie werden Funktionen zur Laufzeit aus dem vtable herausgesucht? Namensvergleich?
Haben rein virtuelle Klassen eigentlich auch einen vtable? Von ihnen kann ja sowieso kein Objekt erstellt werden.

Wenn eine virtuelle Methode in einer Basisklasse public war, eine Unterklasse mit private erbt, die Methode also private übernimmt, was passiert dann, wenn über einen Zeiger auf eine Instanz der Unterklasse die nun private Methode benutzt wird?
 
Zuletzt bearbeitet:
Hab mir einiges inzwischen selbst beantwortet (allerdings ausschlieslich Vermutungen, also berichtigt mich bitte):

Die Methoden der BasisKlassen werden in Reihenfolge der Basisklassen-Aufzählung in den VTable eingefügt, dann werden die Methoden der abgeleiteten Klasse angehängt.

Methoden werden anhand ihres Indizes aus dem VTable gelesen, was aber bedeutet, dass ein Cast eines Pointers nicht nur eine reine Reinterpretation der Bytes bedeutet, sondern bei einem gecasteten Zeiger irgendwie auf einen anderen VTable verwiesen werden muss (wie das umgesetzt wird, ist mir aber schleierhaft, da der VTable-Pointer am Objekt, nicht am Zeiger gespeichert wird und ein Zeiger nicht wissen kann, auf wieviele Objekte er zeigt).

mir hat gesagt.:
Wenn eine virtuelle Methode in einer Basisklasse public war, eine Unterklasse mit private erbt, die Methode also private übernimmt, was passiert dann, wenn über einen Zeiger auf eine Instanz der Unterklasse die nun private Methode benutzt wird?
Logisch... -> woher soll das Programm während der Laufzeit wissen, ob die Stelle an der es gerade ist einen Private-Zugriff auf eine Klassenmethode erlaubt -> wird also einfach ausgeführt.
 
Ich meine, bei Mehrfachvererbung (mehr als eine Basisklasse) bekommt ein Objekt auch mehrere VTable-Pointer.

Dadurch erklärt sich auch (das schon von mir beobachtete Verhalten), dass die Adresse eines Objekt-Pointers UNTERSCHIEDLICH sein kann, je nachdem, welchen Typ der Pointer hat.
Sprich, wenn man einen Pointer auf eine extrem vererbte Klasse (mit mehreren Basisklassen hat) und den mit demselben Objekt (aber Pointer auf Basisklassenobjekt) vergleicht, kann das unterschiedlich sein. Auf diese Eigenart bin ich bei einem MFC-Projekt gestossen, bei dem ein Objekt durch unterschiedliche Pointer-Werte nicht als dasselbe erkannt wurde.

Auch eine Frage:
Warum willst du das mit dem vtable so genau wissen? Ist das denn nicht compiler-spezifisch?
 
Zu dem Schluss bin ich inzwischen auch gekommen.
Dennoch: vorher hab ich darüber nachgedacht und irgendwie trotzdem noch einen Widerspruch darin gefunden (oder etwas mir unerklärliches), jetzt komm ich nicht mehr darauf.
Vielleicht war ich vorher nur zu verpeilt, richtig zu denken, oder jetzt.

Das ist glaub nicht Compiler-spezifisch. Wie will man sonst Interfaces erstellen, wie würde COM arbeiten, wenn jeder Compiler andere VTables machen würde....

Ich brauche das, für mein Verständnis der Arbeitsweise von polymorphen Klassen (ist doch auch ein halbwegs interessantes Thema), und für den Umgang mit der COM-Api.
 
Das ist glaub nicht Compiler-spezifisch. Wie will man sonst Interfaces erstellen, wie würde COM arbeiten, wenn jeder Compiler andere VTables machen würde....
Das ist compilerspezifisch. Und wieso sollte das ein Problem sein für die Interface-Erstellung?
Um die VTables sollte man sich gar nicht kümmern -- das ist ein C++-Implementierungsdetail, das eigentlich keinen C++-Programmierer kümmern sollte, sondern nur die Entwickler. Gut zu wissen, dass es sowas gibt, aber auf keinen Fall etwas, das man bei der Programmierung in Betracht ziehen muss.
 
Zuletzt bearbeitet:
Zurück