Zuerst: ein Konzept betonen

Eine Funktion als virtuell zu definieren bedeutet nicht, dass die Funktion nicht implementiert ist.

Das Definieren als virtuell dient dazu, einen Basisklassenzeiger zu verwenden, um diese Funktion der abgeleiteten Klasse aufzurufen.

Nur das Definieren einer Funktion als rein virtuelle Funktion bedeutet, dass die Funktion nicht implementiert ist.

Das Definieren einer rein virtuellen Funktion dient der Implementierung einer Schnittstelle und fungiert als Spezifikation, die vorschreibt, dass Programmierer, die diese Klasse erben, diese Funktion implementieren müssen.

1. Einführung

Angenommen, wir haben die folgende Klassenhierarchie:

Beispiel

class A { public:     virtual void foo()     {         cout<<"A::foo() wird aufgerufen"<<endl;     } }; class B:public A { public:     void foo()     {         cout<<"B::foo() wird aufgerufen"<<endl;     } }; int main(void) {     A *a = new B();     a->foo();   // Hier ist, obwohl a ein Zeiger auf A ist, die aufgerufene Funktion (foo) die von B!     return 0; }

Dieses Beispiel ist eine typische Anwendung virtueller Funktionen. Anhand dieses Beispiels werden Sie vielleicht ein Gefühl für virtuelle Funktionen bekommen. Virtuell ist es im Sinne der sogenannten "späten Bindung" oder "dynamischen Bindung": Der Aufruf einer Klassenfunktion wird nicht zur Compilezeit, sondern zur Laufzeit bestimmt. Da beim Schreiben von Code nicht bestimmt werden kann, ob die aufgerufene Funktion die der Basisklasse oder die welcher abgeleiteten Klasse ist, nennt man sie eine "virtuelle" Funktion.

Virtuelle Funktionen können Polymorphismus nur mit Hilfe von Zeigern oder Referenzen erreichen.


Reine virtuelle Funktionen in C++

1. Definition

 

Eine rein virtuelle Funktion ist eine in der Basisklasse deklarierte virtuelle Funktion. Sie hat keine Definition in der Basisklasse, verlangt aber, dass jede abgeleitete Klasse ihre eigene Implementierungsmethode definiert. Um eine rein virtuelle Funktion in der Basisklasse zu implementieren, fügt man nach dem Funktionsprototyp=0:

 
virtual void funtion1()=0

2. Gründe für die Einführung

  

1. Um Polymorphie bequem nutzen zu können, müssen wir oft virtuelle Funktionen in der Basisklasse definieren.

  

2. In vielen Fällen ist es unvernünftig, dass die Basisklasse selbst Objekte erzeugt. Zum Beispiel kann ein Tier als Basisklasse Unterklassen wie Tiger und Pfau ableiten, aber ein Objekt vom Tier selbst zu erzeugen, ist offensichtlich unvernünftig.

  

Um die oben genannten Probleme zu lösen, wird das Konzept der rein virtuellen Funktionen eingeführt und die Funktion als rein virtuelle Funktion definiert (Methode:virtual ReturnType Function()= 0;), dann verlangt der Compiler, dass sie in abgeleiteten Klassen überschrieben werden muss, um Polymorphie zu erreichen. Gleichzeitig wird eine Klasse, die rein virtuelle Funktionen enthält, als abstrakte Klasse bezeichnet, die keine Objekte erzeugen kann. Dies löst die beiden oben genannten Probleme auf schöne Weise.

Eine Klasse, die eine rein virtuelle Funktion deklariert, ist eine abstrakte Klasse. Daher können Benutzer keine Instanzen der Klasse erstellen, sondern nur Instanzen ihrer abgeleiteten Klassen.

Das bemerkenswerteste Merkmal rein virtueller Funktionen ist: Sie müssen die Funktion in der erbenden Klasse erneut deklarieren (das folgende =0 nicht angeben, sonst kann auch die abgeleitete Klasse nicht instanziiert werden), und sie haben oft keine Definition in der abstrakten Klasse.

Der Zweck der Definition rein virtueller Funktionen besteht darin, dass abgeleitete Klassen nur die Schnittstelle der Funktion erben.

Die Bedeutung rein virtueller Funktionen besteht darin, allen Klassenobjekten (hauptsächlich Objekten abgeleiteter Klassen) zu ermöglichen, die Aktionen der rein virtuellen Funktion auszuführen, aber die Klasse kann keine vernünftige Standardimplementierung für die rein virtuelle Funktion bereitstellen. Daher teilt die Deklaration einer rein virtuellen Funktion in einer Klasse den Designern von Unterklassen mit: „Sie müssen eine Implementierung der rein virtuellen Funktion bereitstellen, aber ich weiß nicht, wie Sie sie implementieren werden.“


Einführung in abstrakte Klassen

Eine abstrakte Klasse ist eine spezielle Klasse, die zu Zwecken der Abstraktion und des Entwurfs eingerichtet wurde. Sie steht auf einer höheren Ebene der Vererbungshierarchie.

(1) Definition einer abstrakten Klasse:Eine Klasse mit rein virtuellen Funktionen wird als abstrakte Klasse bezeichnet.

(2) Rolle einer abstrakten Klasse:Die Hauptrolle einer abstrakten Klasse besteht darin, zugehörige Operationen als Schnittstellen in einer Vererbungshierarchie zu organisieren, sodass sie eine gemeinsame Wurzel für abgeleitete Klassen bereitstellt. Abgeleitete Klassen werden die Operationen, die in ihrer Basisklasse als Schnittstellen dienen, konkret implementieren. Daher beschreibt eine abgeleitete Klasse tatsächlich die gemeinsame Semantik einer Gruppe von Operationsschnittstellen ihrer Unterklassen. Diese Semantik wird auch an Unterklassen weitergegeben, die diese Semantik konkret implementieren oder an ihre eigenen Unterklassen weitergeben können.

(3) Hinweise bei der Verwendung abstrakter Klassen:

  • Eine abstrakte Klasse kann nur als Basisklasse verwendet werden, und ihre rein virtuellen Funktionen werden von abgeleiteten Klassen implementiert. Wenn eine abgeleitete Klasse die rein virtuellen Funktionen nicht neu definiert, sondern nur die rein virtuellen Funktionen von der Basisklasse erbt, dann ist diese abgeleitete Klasse weiterhin eine abstrakte Klasse. Wenn eine abgeleitete Klasse Implementierungen für die rein virtuellen Funktionen der Basisklasse bereitstellt, dann ist diese abgeleitete Klasse keine abstrakte Klasse mehr; sie ist eine konkrete Klasse, von der Objekte erzeugt werden können.
  • Abstrakte Klassen können keine Objekte definieren.

Zusammenfassung:

  • 1. Eine rein virtuelle Funktion wird wie folgt deklariert:virtual void funtion1()=0;Eine rein virtuelle Funktion hat notwendigerweise keine Definition. Rein virtuelle Funktionen werden verwendet, um das Verhalten abgeleiteter Klassen zu standardisieren, d. h. die Schnittstelle. Eine Klasse, die rein virtuelle Funktionen enthält, ist eine abstrakte Klasse. Eine abstrakte Klasse kann keine Instanzen definieren, aber es können Zeiger oder Referenzen auf konkrete Klassen deklariert werden, die die abstrakte Klasse implementieren.

  • 2. Eine virtuelle Funktion wird wie folgt deklariert:virtual ReturnType FunctionName(Parameter)Eine virtuelle Funktion muss implementiert werden. Wenn sie nicht implementiert wird, meldet der Compiler einen Fehler mit der Fehlermeldung:

    error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"
  • 3. Bei virtuellen Funktionen haben sowohl die Elternklasse als auch die Kindklasse ihre eigenen Versionen. Wenn sie auf polymorphe Weise aufgerufen werden, werden sie dynamisch gebunden.

  • 4. In einer Unterklasse, die eine rein virtuelle Funktion implementiert, wird diese rein virtuelle Funktion zu einer virtuellen Funktion in der Unterklasse. Die Unterklasse der Unterklasse, d. h. die Enkelklasse, kann diese virtuelle Funktion überschreiben, und sie wird dynamisch gebunden, wenn sie auf polymorphe Weise aufgerufen wird.

  • 5. Virtuelle Funktionen sind der Mechanismus in C++, der zur Implementierung von Polymorphie verwendet wird. Die Kernidee besteht darin, über Basisklassen auf Funktionen zuzugreifen, die in abgeleiteten Klassen definiert sind.

  • 6. Bei der dynamischen Speicherzuweisung auf dem Heap muss der Destruktor eine virtuelle Funktion sein, er muss jedoch nicht rein virtuell sein.

  • 7. Friend-Funktionen sind keine Memberfunktionen. Nur Memberfunktionen können virtuell sein, also können Friend-Funktionen keine virtuellen Funktionen sein. Das virtuelle Problem von Friend-Funktionen kann jedoch gelöst werden, indem Friend-Funktionen virtuelle Memberfunktionen aufrufen.

  • 8. Der Destruktor sollte eine virtuelle Funktion sein, damit der Destruktor des entsprechenden Objekttyps aufgerufen wird. Wenn der Zeiger also auf ein Unterklassenobjekt zeigt, wird der Destruktor der Unterklasse aufgerufen, und danach automatisch der Destruktor der Basisklasse.

Eine Klasse mit rein virtuellen Funktionen ist eine abstrakte Klasse; sie kann keine Objekte erzeugen und kann nur abgeleitet werden. Wenn die rein virtuellen Funktionen ihrer abgeleiteten Klasse nicht überschrieben wurden, ist ihre abgeleitete Klasse weiterhin eine abstrakte Klasse.

Rein virtuelle Funktionen zu definieren, macht die Basisklasse nicht instanziierbar, denn eine solche abstrakte Datenstruktur zu instanziieren ist an sich sinnlos, und eine Implementierung bereitzustellen ist ebenfalls sinnlos.

Eigentlich dienen rein virtuelle Funktionen meiner persönlichen Meinung nach zwei Zwecken:

  • 1. Zur Sicherheit: um unbekannte Ergebnisse durch Nachlässigkeit dort zu vermeiden, wo eine explizite Implementierung nötig ist, und um Unterklassen daran zu erinnern, umzusetzen, was sie umsetzen sollten.
  • 2. Zur Effizienz: nicht die Effizienz der Programmausführung, sondern die Effizienz des Codierens.

Original-URL: https://blog.csdn.net/hackbuteer1/article/details/7558868