2010-02-11 15 views
19

Ich sah Code in einer abgeleiteten Klasse vor kurzem, in dem der Programmierer virtual vor den Funktionen überschrieben. Ist das üblich? Ich fand es sehr merkwürdig und es überraschte mich irgendwie.Verwenden von 'virtuellen' in abgeleiteten Klasse

Edit: Ich frage nicht, was virtuelle tut, ich frage, warum jemand virtuell in einer abgeleiteten Klasse setzen würde, die bereits virtuelle Funktionen in seiner Basisklasse überschreibt.

EX:

class B { 
public: 
    virtual void foo(); 
    .... 
}; 

class D : public B { 
public: 
    virtual void foo(); // could have just put void foo(); 
    ... 
}; 
+4

Ich mache das auch immer, nur um meinen Code zu dokumentieren. –

+3

Dies ist etwas, wo ich denke, C# ist besser, indem abgeleitete Klassen zwingen, das 'override' Schlüsselwort zu verwenden. – dalle

+0

Das ist die perfekte Frage, die viele meiner Fragen beantwortet, wie virtuell funktioniert. Danke @Person –

Antwort

25

virtual für überschreibbar Funktionen auf höchster (least abgeleitet) Stufe benötigt wird. Es ist optional, aber auf niedrigeren (abgeleiteten) Ebenen harmlos. Es ist gut, den Code selbst zu dokumentieren.

+3

Genau. Der Compiler weiß es bereits, aber andere Personen, die Ihren Code lesen, müssen möglicherweise mehrere Header-Dateien zurückverfolgen, um das herauszufinden. –

3

Ich gehe davon aus, dass Sie den Zweck des virtuellen Schlüsselwortes kennen, sich aber wundern, warum es plötzlich in einem Subtyp auftritt. Wenn ich mich irre, wird meine Antwort wahrscheinlich keinen Sinn ergeben, aber jede C++ - Referenz reicht aus.

Es ist vollkommen legal, virtuell in eine abgeleitete Klasse zu setzen. Wenn Sie eine Referenz oder einen Zeiger auf diese Klasse oder eine ihrer Unterklassen haben, werden Aufrufe dieser Funktion daher basierend auf dem Laufzeittyp dynamisch gebunden.

Während es legal ist, wird es nicht als gutes Design angesehen, eine nichtvirtuelle Methode in der Basisklasse und virtuell in einer überschriebenen Version zu haben.

Ein Grund ist, dass Sie eine Instanz der abgeleiteten Klasse haben könnten, und dann einen Zeiger auf die Basis und einen Zeiger auf die abgeleitete, und beide Zeiger auf diese Instanz haben. Das Aufrufen derselben Funktion für jeden Zeiger würde dann ein anderes Ergebnis haben, da das Aufrufen des mit der Basisklasse deklarierten Zeigers auf die Definition in der Basisklasse abzielen würde.

4

Ich sehe nichts merkwürdiges darin. In vielen Fällen (wenn nicht die meiste Zeit) erstellen Programmierer die Deklaration der überschreibenden Funktion in der abgeleiteten Klasse, indem sie sie aus der Basisklasse kopieren. Es hat keinen Sinn, die zusätzliche Anstrengung aufzuwenden, den redundanten virtual Spezifizierer manuell zu entfernen. Darüber hinaus macht es das explizite virtual einfacher zu sehen, welche Funktionen virtuell sind.

8

Es ist sehr häufig. Viele Stilführer empfehlen es, z.B. Google. Der Zweck besteht darin, die Lesbarkeit des Codes zu verbessern.

+1

Link funktioniert nicht –

+0

Neuer Link hier http://google.github.io/styleguide/cppguide.html#Inheritance Der Link sagt 'override' oder' virtual' *, aber nicht beide *. –

1

Dies wird helfen, wenn auch zukünftige Ableitungen. Wenn jemand will, Klasse D abzuleiten und virtuelle Funktionen haben, dann ist es leicht zu verstehen

4

Eine weitere Möglichkeit, die Lesbarkeit zu verbessern ist, so etwas zu verwenden:

class B { 
public: 
    virtual void foo(); 
    .... 
}; 

class D : public B { 
public: 
    /*override*/ void foo(); 
    ... 
}; 
3

Diese Antworten (und diese Praxis) sind veraltet . Ab C++ 11 sollten Sie die override keyword verwenden, um explizit anzugeben, dass eine virtuelle Funktion eine andere virtuelle Funktion überschreibt. Ihr Compiler wird einen Fehler auslösen, wenn Sie versuchen, override etwas, das keine virtuelle Funktion in der Basisklasse ist!

Verwandte Themen