logo

Чисті віртуальні функції та абстрактні класи в C++

Іноді реалізація всіх функцій не може бути забезпечена в базовому класі, тому що ми не знаємо реалізації. Такий клас називається an абстрактний клас Наприклад, нехай Shape буде базовим класом. Ми не можемо забезпечити реалізацію функції draw() у Shape, але ми знаємо, що кожен похідний клас повинен мати реалізацію draw(). Так само клас Animal не має реалізації move() (припускається, що всі тварини рухаються), але всі тварини повинні знати, як рухатися. Ми не можемо створювати об'єкти абстрактних класів.

А чиста віртуальна функція (або абстрактна функція) у C++ — це віртуальна функція, для якої ми можемо мати реалізацію, але ми повинні перевизначити цю функцію в похідному класі, інакше похідний клас також стане абстрактним класом. Чиста віртуальна функція оголошується шляхом присвоєння 0 в декларації.

Приклад чистих віртуальних функцій

C++






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

структури даних в java

>

>

Повний приклад

Чиста віртуальна функція реалізується класами, які є похідними від абстрактного класу.

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

>

>

Вихід

fun() called>

Деякі цікаві факти

1. Клас є абстрактним, якщо він має хоча б одну чисту віртуальну функцію.

приклад

У наведеному нижче коді C++ Test є абстрактним класом, оскільки він має чисту віртуальну функцію 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;> }>

>

>

Вихід

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. Ми можемо мати покажчики та посилання типу абстрактного класу.

Наприклад, наступна програма працює нормально.

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->показати ();> >return> 0;> }>

Команди Linux створити папку
>

>

Вихід

In Derived>

3. Якщо ми не перевизначаємо чисту віртуальну функцію в похідному класі, тоді похідний клас також стає абстрактним класом.

Наступний приклад демонструє те саме.

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

>

Редьярд Кіплінг якщо пояснення

>

Вихід

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. Абстрактний клас може мати конструктори.

Наприклад, наступна програма компілюється та працює нормально.

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

>

>

Вихід

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

5. Абстрактний клас у C++ також може бути визначений за допомогою ключового слова struct.

приклад

що таке сплячий режим в java
struct shapeClass { virtual void Draw()=0; }>

Порівняння з Java

У Java клас можна зробити абстрактним за допомогою ключового слова abstract. Так само функцію можна зробити чисто віртуальною або абстрактною за допомогою ключового слова abstract. Побачити Абстрактні класи в Java для більш детальної інформації.

Інтерфейс проти абстрактних класів

Інтерфейс не має реалізації жодного зі своїх методів, його можна розглядати як набір оголошень методів. У C++ інтерфейс можна моделювати, зробивши всі методи чисто віртуальними. У Java існує окреме ключове слово для інтерфейсу.

Ми можемо розглядати інтерфейс як файли заголовків у C++, наприклад, у файлах заголовків ми надаємо лише тіло класу, який збирається його реалізувати. Так само в Java в інтерфейсі ми надаємо лише тіло класу та пишемо фактичний код у будь-якому класі, який його реалізує.