logo

Reine virtuelle Funktionen und abstrakte Klassen in C++

Manchmal kann die Implementierung aller Funktionen nicht in einer Basisklasse bereitgestellt werden, weil wir die Implementierung nicht kennen. Eine solche Klasse heißt an abstrakte Klasse .Lassen Sie beispielsweise Shape eine Basisklasse sein. Wir können die Implementierung der Funktion draw() in Shape nicht bereitstellen, aber wir wissen, dass jede abgeleitete Klasse eine Implementierung von draw() haben muss. Ebenso verfügt eine Animal-Klasse nicht über die Implementierung von move() (vorausgesetzt, dass sich alle Tiere bewegen), aber alle Tiere müssen wissen, wie sie sich bewegen. Wir können keine Objekte abstrakter Klassen erstellen.

A rein virtuelle Funktion (oder abstrakte Funktion) in C++ ist eine virtuelle Funktion, für die wir eine Implementierung haben können. Wir müssen diese Funktion jedoch in der abgeleiteten Klasse überschreiben, sonst wird die abgeleitete Klasse ebenfalls zu einer abstrakten Klasse. Eine rein virtuelle Funktion wird durch die Zuweisung von 0 in der Deklaration deklariert.

Beispiel für rein virtuelle Funktionen

C++






// An abstract class> class> Test {> >// Data members of class> public>:> >// Pure Virtual Function> >virtual> void> show() = 0;> >/* Other members */> };>

>

>

Vollständiges Beispiel

Eine rein virtuelle Funktion wird durch Klassen implementiert, die von einer abstrakten Klasse abgeleitet sind.

C++




// C++ Program to illustrate the abstract class and virtual> // functions> #include> using> namespace> std;> class> Base {> >// private member variable> >int> x;> public>:> >// pure virtual function> >virtual> void> fun() = 0;> >// getter function to access x> >int> getX() {>return> x; }> };> // This class inherits from Base and implements fun()> class> Derived :>public> Base {> >// private member variable> >int> y;> public>:> >// implementation of the pure virtual function> >void> fun() { cout <<>'fun() called'>; }> };> int> main(>void>)> {> >// creating an object of Derived class> >Derived d;> >// calling the fun() function of Derived class> >d.fun();> >return> 0;> }>

>

>

Ausgabe

fun() called>

Einige interessante Fakten

1. Eine Klasse ist abstrakt, wenn sie mindestens eine rein virtuelle Funktion hat.

Beispiel

Im folgenden C++-Code ist Test eine abstrakte Klasse, da sie über eine rein virtuelle Funktion show() verfügt.

C++




// C++ program to illustrate the abstract class with pure> // virtual functions> #include> using> namespace> std;> class> Test {> >// private member variable> >int> x;> public>:> >// pure virtual function> >virtual> void> show() = 0;> >// getter function to access x> >int> getX() {>return> x; }> };> int> main(>void>)> {> >// Error: Cannot instantiate an abstract class> >Test t;> >return> 0;> }>

>

>

Ausgabe

Compiler Error: cannot declare variable 't' to be of abstract type 'Test' because the following virtual functions are pure within 'Test': note: virtual void Test::show()>

2. Wir können Zeiger und Referenzen vom abstrakten Klassentyp haben.

Das folgende Programm funktioniert beispielsweise einwandfrei.

C++

Java-Programm




// C++ program that demonstrate that> // we can have pointers and references> // of abstract class type.> #include> using> namespace> std;> class> Base {> public>:> >// pure virtual function> >virtual> void> show() = 0;> };> class> Derived :>public> Base {> public>:> >// implementation of the pure virtual function> >void> show() { cout <<>'In Derived '>; }> };> int> main(>void>)> {> >// creating a pointer of type> >// Base pointing to an object> >// of type Derived> >Base* bp =>new> Derived();> >// calling the show() function using the> >// pointer> >bp->show();> >return> 0;> }>

>

>

Ausgabe

In Derived>

3. Wenn wir die rein virtuelle Funktion in der abgeleiteten Klasse nicht überschreiben, wird auch die abgeleitete Klasse zu einer abstrakten Klasse.

Das folgende Beispiel zeigt dasselbe.

C++




// C++ program to demonstrate that if we do not override> // the pure virtual function in the derived class, then> // the derived class also becomes an abstract class> #include> using> namespace> std;> class> Base {> public>:> >// pure virtual function> >virtual> void> show() = 0;> };> class> Derived :>public> Base {> };> int> main(>void>)> {> >// creating an object of Derived class> >Derived d;> >return> 0;> }>

>

>

Ausgabe

Compiler Error: cannot declare variable 'd' to be of abstract type 'Derived' because the following virtual functions are pure within 'Derived': virtual void Base::show()>

4. Eine abstrakte Klasse kann Konstruktoren haben.

Das folgende Programm lässt sich beispielsweise kompilieren und läuft einwandfrei.

C++




// C++ program to demonstrate that> // an abstract class can have constructors.> #include> using> namespace> std;> // An abstract class with constructor> class> Base {> protected>:> >// protected member variable> >int> x;> public>:> >// pure virtual function> >virtual> void> fun() = 0;> >// constructor of Base class> >Base(>int> i)> >{> >x = i;> >cout <<>'Constructor of base called '>;> >}> };> class> Derived :>public> Base {> >// private member variable> >int> y;> public>:> >// calling the constructor of Base class> >Derived(>int> i,>int> j)> >: Base(i)> >{> >y = j;> >}> >// implementation of pure virtual function> >void> fun()> >{> >cout <<>'x = '> << x <<>', y = '> << y <<>' '>;> >}> };> int> main(>void>)> {> >// creating an object of Derived class> >Derived d(4, 5);> >// calling the fun() function of Derived class> >d.fun();> >// creating an object of Derived class using> >// a pointer of the Base class> >Base* ptr =>new> Derived(6, 7);> >// calling the fun() function using the> >// pointer> >ptr->fun();> >return> 0;> }>

>

>

Ausgabe

Constructor of base called x = 4, y = 5 Constructor of base called x = 6, y = 7>

5. Eine abstrakte Klasse in C++ kann auch mit dem Schlüsselwort struct definiert werden.

Beispiel

struct shapeClass { virtual void Draw()=0; }>

Vergleich mit Java

In Java kann eine Klasse mithilfe eines abstrakten Schlüsselworts abstrakt gemacht werden. Ebenso kann eine Funktion mithilfe eines abstrakten Schlüsselworts rein virtuell oder abstrakt gemacht werden. Sehen Abstrakte Klassen in Java für mehr Details.

Schnittstelle vs. abstrakte Klassen

Eine Schnittstelle verfügt über keine Implementierung einer ihrer Methoden, sie kann als Sammlung von Methodendeklarationen betrachtet werden. In C++ kann eine Schnittstelle simuliert werden, indem alle Methoden rein virtuell gemacht werden. In Java gibt es ein eigenes Schlüsselwort für die Schnittstelle.

Wir können uns Interface als Header-Dateien in C++ vorstellen, so wie wir in Header-Dateien nur den Hauptteil der Klasse bereitstellen, die ihn implementieren wird. In ähnlicher Weise stellen wir in Java im Interface nur den Hauptteil der Klasse bereit und schreiben den eigentlichen Code in die Klasse, die ihn implementiert.