logo

Rena virtuella funktioner och abstrakta klasser i C++

Ibland kan implementering av alla funktioner inte tillhandahållas i en basklass eftersom vi inte känner till implementeringen. En sådan klass kallas en abstrakt klass . Låt till exempel Shape vara en basklass. Vi kan inte tillhandahålla implementeringen av funktionen draw() i Shape, men vi vet att varje härledd klass måste ha en implementering av draw(). På samma sätt har en djurklass inte implementeringen av move() (förutsatt att alla djur rör sig), men alla djur måste veta hur de ska röra sig. Vi kan inte skapa objekt av abstrakta klasser.

A ren virtuell funktion (eller abstrakt funktion) i C++ är en virtuell funktion för vilken vi kan ha en implementering, men vi måste åsidosätta den funktionen i den härledda klassen, annars kommer den härledda klassen också att bli en abstrakt klass. En ren virtuell funktion deklareras genom att tilldela 0 i deklarationen.

Exempel på rena virtuella funktioner

C++






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

>

>

Komplett exempel

En ren virtuell funktion implementeras av klasser som är härledda från en abstrakt klass.

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;> }>

>

npm rensa cache
>

Produktion

fun() called>

Några intressanta fakta

1. En klass är abstrakt om den har minst en ren virtuell funktion.

Exempel

I C++-koden nedan är Test en abstrakt klass eftersom den har en ren virtuell funktion show().

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;> }>

>

>

Produktion

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. Vi kan ha pekare och referenser av abstrakt klasstyp.

Till exempel fungerar följande program bra.

C++




// 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->visa();> >return> 0;> }>

>

>

Produktion

In Derived>

3. Om vi ​​inte åsidosätter den rena virtuella funktionen i den härledda klassen, så blir den härledda klassen också en abstrakt klass.

Följande exempel visar detsamma.

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;> }>

>

>

maskinskriven var och en

Produktion

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. En abstrakt klass kan ha konstruktorer.

Till exempel, följande program kompilerar och fungerar bra.

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;> }>

>

>

Produktion

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

5. En abstrakt klass i C++ kan också definieras med nyckelordet struct.

Exempel

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

Jämförelse med Java

I Java kan en klass göras abstrakt genom att använda ett abstrakt nyckelord. På samma sätt kan en funktion göras ren virtuell eller abstrakt genom att använda ett abstrakt nyckelord. Ser Abstrakta klasser i Java för mer detaljer.

Gränssnitt vs abstrakta klasser

Ett gränssnitt har inte en implementering av någon av dess metoder, det kan betraktas som en samling metoddeklarationer. I C++ kan ett gränssnitt simuleras genom att göra alla metoder rena virtuella. I Java finns ett separat nyckelord för gränssnittet.

Vi kan tänka på Interface som header-filer i C++, som i header-filer tillhandahåller vi bara kroppen av klassen som ska implementera den. På samma sätt i Java i Interface tillhandahåller vi bara kroppen av klassen och vi skriver den faktiska koden i vilken klass som än implementerar den.