Virtuelle Vererbung und statische Vererbung - Mischen in C ++

9

Wenn Sie so etwas haben:

%Vor%

Wird func () dynamisch ausgelöst?
Wie könnten Sie Klasse A implementieren, so dass, wenn B eine virtuelle Überschreibung hat, dass es dynamisch ausgelöst wird, aber statisch ausgelöst wird, wenn B nicht?

Bearbeiten: Mein Code wurde nicht kompiliert? Tut mir leid, Leute. Ich bin gerade ziemlich krank. Mein neuer Code wird auch nicht kompiliert, aber das ist ein Teil der Frage. Auch diese Frage ist für mich, nicht die Frage.

%Vor%     
Puppy 19.11.2010, 00:45
quelle

6 Antworten

2

Ich bin mir nicht sicher, ob ich verstehe, was Sie fragen, aber es scheint, dass Ihnen die essenzielle CRTP-Besetzung fehlt:

%Vor%

Wenn T seinen eigenen func nicht deklariert, wird dies eine unendliche Rekursion sein, da self.func A & lt; T & gt; :: func findet. Dies gilt auch dann, wenn eine abgeleitete Klasse von T (z. B. DV unten) ihre eigene Funktion deklariert, T jedoch nicht.

Testen Sie mit verschiedenen endgültigen Overrider, um Versand funktioniert wie angekündigt zu zeigen:

%Vor%     
Fred Nurk 19.11.2010, 06:56
quelle
1
  

Wie können Sie die Klasse A so implementieren, dass, wenn B eine virtuelle Überschreibung hat, diese dynamisch gesendet wird, aber statisch, wenn B nicht ausgeführt wird?

Etwas widersprüchlich, nicht wahr? Ein Benutzer der Klasse A weiß möglicherweise nichts über B oder C. Wenn Sie einen Verweis auf ein A haben, können Sie nur herausfinden, ob func() dynamischen Versand benötigt, indem Sie sich an die vtable wenden. Da A::func() nicht virtuell ist, gibt es keinen Eintrag dafür und somit auch keine Informationen. Sobald Sie es virtuell machen, konsultieren Sie die vtable und es ist dynamischer Versand.

Die einzige Möglichkeit, direkte Funktionsaufrufe (oder Inlines) zu erhalten, wäre mit nicht-virtuellen Funktionen und ohne Indirektion durch Basisklassenzeiger.

Edit: Ich denke, das Idiom dafür in Scala wäre class C: public B, public A<C> (Wiederholung des Merkmals mit der Kindklasse), aber das funktioniert nicht in C ++, weil es die Mitglieder von A<T> in C .deutig macht / p>     

Ben Jackson 19.11.2010 01:25
quelle
1

In Ihrem speziellen Beispiel ist kein dynamischer Versand erforderlich, da der Typ von c zum Zeitpunkt der Kompilierung bekannt ist. Der Aufruf von B::func wird fest codiert.

Wenn Sie func über B* aufrufen würden, würden Sie eine virtuelle Funktion aufrufen. Aber in Ihrem hochkomplizierten Beispiel würde das Sie wieder zu B::func bringen.

Es macht wenig Sinn, über den dynamischen Versand von A* zu sprechen, da A eine Vorlagenklasse ist - Sie können keinen generischen A erstellen, nur einen, der an eine bestimmte Unterklasse gebunden ist.

    
Mark Ransom 19.11.2010 03:52
quelle
1
  

Wie können Sie die Klasse A so implementieren, dass, wenn B eine virtuelle Überschreibung hat, diese dynamisch gesendet wird, aber statisch, wenn B nicht?

Wie andere bemerkt haben, ist es wirklich schwer, diese Frage zu verstehen, aber ich erinnerte mich an etwas, das ich vor langer Zeit gelernt habe. Hier ist eine sehr lange Einstellung, um Ihre Frage zu beantworten:

%Vor%

Da hängt% A davon ab, ob func() virtuell ist. Wenn Base es als virtual deklariert, wird es auch in A virtuell sein. Sonst wird es nicht. Siehe dies:

%Vor%

Würde dies Ihre Frage beantworten?

    
sbi 19.11.2010 06:11
quelle
0

Ob die Funktion dynamisch ausgelöst wird oder nicht, hängt von zwei Dingen ab:

a) Ob der Objektausdruck ein Referenz- oder Zeigertyp ist

b) ob die Funktion (zu der die Überladungsauflösung aufgelöst wird) virtuell ist oder nicht.

Kommen Sie jetzt zu Ihrem Code:

%Vor%

Kurz gesagt, 'func' wird nicht dynamisch ausgelöst.

Beachten Sie, dass :: der Aufrufmechanismus für virtuelle Funktionen unterdrückt wird.

  

$ 10.3 / 12- "Explizite Qualifikation mit   der Bereichsoperator (5.1) unterdrückt   der virtuelle "Anrufmechanismus".

Der Code in OP2 gibt einen Fehler, weil die Syntax X :: Y verwendet werden kann, um 'Y' im Bereich von 'X' nur dann aufzurufen, wenn 'Y' ein statisches Element im Bereich von 'X' ist.

    
Chubsdad 19.11.2010 08:57
quelle
-1

Es scheint, dass Sie nur eine kleine Spur und Verwendung hinzufügen mussten, um Ihre eigene Frage zu beantworten ...

%Vor%

Ausgabe:

%Vor%

Fazit: A nimmt die Virtualität von B's Funktion an.

    
Tony Delroy 19.11.2010 03:13
quelle

Tags und Links