2010-02-09 6 views
6

Angenommen, ich eine Diamant Erbe Situation wie folgt:Warum hat die folgende Klasse eine virtuelle Tabelle?

class A{ 
    public: virtual void foo(){}; 
}; 
class B: public virtual A{ 
    public: virtual void foo(){}; 
}; 
class C: public virtual A{ 
    public: virtual void foo(){}; 
}; 
class D: B, C{}; 

Die letzte Zeile liefert unter Berufung auf Mehrdeutigkeit einen Übersetzungsfehler. Wie ich es verstehe, ist das Problem, dass der Compiler nicht weiß, welches foo in D's vtbl zu platzieren ist, aber warum würde es sogar ein vtbl für D geben, wenn es keine eigenen virtuellen Funktionen definiert?

+0

Ist "virtual" als Schutzlevel-Spezifizierer sogar gültig für Ihre Klassendeklarationszeilen (z. B. Klasse B: virtuelles A)? – Joe

+4

Es ist kein Schutzspezifizierer. Es bezeichnet eine virtuelle Basisklasse, die eine Art legaler Hack ist, um das Diamantproblem zu umgehen. –

+0

Ah, richtig, danke. – Joe

Antwort

7

Sie erben Klassen, die virtuelle Funktionen enthalten. Daher hat Ihre Klasse virtuelle Funktionen. So einfach ist das.

+0

Dann fehlt mir vielleicht etwas, denn wenn ich das Wort "virtual" aus der Vererbungsspezifikation (Klasse B: A, Klasse C: A) entferne, kompiliert es und läuft. Sollte das Problem nicht anhalten, weil ich "Klassen erwerbe, die virtuelle Funktionen enthalten"? – EpsilonVector

+0

Sorry das war Klasse B: public A, und so weiter ... – EpsilonVector

+0

Entfernen Sie das Schlüsselwort 'virtual' aus den Methodendeklarationen in' Klasse B' und 'Klasse C'. Neu kompilieren und sehen, was passiert. –