logo

Funcions virtuals pures i classes abstractes en C++

De vegades, la implementació de totes les funcions no es pot proporcionar en una classe base perquè no coneixem la implementació. Aquesta classe s'anomena an classe abstracta .Per exemple, deixem que Shape sigui una classe base. No podem proporcionar la implementació de la funció draw() a Shape, però sabem que cada classe derivada ha de tenir una implementació de draw(). De la mateixa manera, una classe Animal no té la implementació de move() (suposant que tots els animals es mouen), però tots els animals han de saber moure's. No podem crear objectes de classes abstractes.

A funció virtual pura (o funció abstracta) en C++ és una funció virtual per a la qual podem tenir una implementació, però hem d'anul·lar aquesta funció a la classe derivada, en cas contrari, la classe derivada també es convertirà en una classe abstracta. Una funció virtual pura es declara assignant 0 a la declaració.



Exemple de funcions virtuals pures

C++






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



>

>

Exemple complet

Una funció virtual pura és implementada per classes que es deriven d'una classe abstracta.

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

>

>

Sortida

fun() called>

Alguns fets interessants

1. Una classe és abstracta si té almenys una funció virtual pura.

Exemple

Al codi C++ següent, Test és una classe abstracta perquè té una funció virtual pura 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;> }>

>

>

Sortida

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. Podem tenir punters i referències de tipus de classe abstracta.

Per exemple, el programa següent funciona bé.

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

caràcter a int en java
>

>

Sortida

In Derived>

3. Si no substituïm la funció virtual pura a la classe derivada, aleshores la classe derivada també esdevé una classe abstracta.

L'exemple següent demostra el mateix.

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

>

>

Sortida

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. Una classe abstracta pot tenir constructors.

Per exemple, el programa següent es compila i funciona bé.

C++




algorisme dfs

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

>

>

Sortida

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

5. També es pot definir una classe abstracta en C++ utilitzant la paraula clau struct.

Exemple

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

Comparació amb Java

A Java, una classe es pot fer abstracta utilitzant una paraula clau abstracta. De la mateixa manera, una funció es pot convertir en pura virtual o abstracta utilitzant una paraula clau abstracta. Vegeu Classes abstractes en Java per a més detalls.

Interfície vs classes abstractes

Una interfície no té una implementació de cap dels seus mètodes, es pot considerar com una col·lecció de declaracions de mètodes. En C++, es pot simular una interfície fent que tots els mètodes siguin purs virtuals. A Java, hi ha una paraula clau independent per a la interfície.

Podem pensar en la interfície com a fitxers de capçalera en C++, com en els fitxers de capçalera només proporcionem el cos de la classe que l'implementarà. De la mateixa manera, a Java a la interfície només proporcionem el cos de la classe i escrivim el codi real en qualsevol classe que l'implementa.