C++ Поліморфізм із прикладом

Що таке поліморфізм C++?

In C++, поліморфізм призводить до того, що функція-член поводиться по-різному залежно від об’єкта, який її викликає/викликає. Поліморфізм - грецьке слово, що означає мати багато форм. Це відбувається, коли у вас є ієрархія класів, пов’язаних успадкуванням.

Наприклад, припустимо, що у нас є функція makeSound(). Коли кіт викликає цю функцію, він видає звук нявкання. Коли корова викликає ту саму функцію, вона видає звук кашкання.

Поліморфізм в C++

Хоча ми маємо одну функцію, вона поводиться по-різному за різних обставин. Функція має багато форм; отже, ми досягли поліморфізму.

Види поліморфізму

C++ підтримує два типи поліморфізму:

  • Поліморфізм під час компіляції та
  • Поліморфізм часу виконання.

Види поліморфізму

Поліморфізм часу компіляції

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

Поліморфізм під час компіляції досягається через перевантаження функцій і операторів.

Перевантаження функцій

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

Приклад 1

#include <iostream> 
using namespace std;

void test(int i) {
	cout << " The int is " << i << endl;
}
void test(double  f) {
	cout << " The float is " << f << endl;
}
void test(char const *ch) {
	cout << " The char* is " << ch << endl;
}

int main() {
	test(5);
	test(5.5);
	test("five");
	return 0;
}

вихід:

Перевантаження функцій

Ось скріншот коду:

Перевантаження функцій

Пояснення коду:

  1. Включіть файл заголовка iostream у наш код. Ми зможемо використовувати його функції.
  2. Включіть простір імен std у наш код. Ми зможемо використовувати його класи, не викликаючи його.
  3. Створіть функцію під назвою test, яка приймає цілочисельний параметр i. { позначає початок тіла функціонального тесту.
  4. Інструкція, яка буде виконана, якщо запущено/викликається наведений вище функціональний тест.
  5. Кінець основної частини вищевказаного функціонального тесту.
  6. Створіть функцію під назвою test, яка приймає параметр f з плаваючою речовиною. { позначає початок тіла функціонального тесту.
  7. Інструкція, яка буде виконана, якщо запущено/викликається наведений вище функціональний тест.
  8. Кінець тіла вищевказаного функціонального тесту.
  9. Створіть функцію під назвою test, яка приймає символьний параметр ch. { позначає початок тіла функціонального тесту.
  10. Інструкція, яка буде виконана, якщо запущено/викликається наведений вище функціональний тест.
  11. Кінець тіла вищевказаного функціонального тесту.
  12. Виклик функції main(). { позначає початок тіла функції.
  13. Викличте перевірку функції та передайте їй 5 як значення аргументу. Це викликає тестову функцію, яка приймає цілочисельний аргумент, тобто першу тестову функцію.
  14. Викличте перевірку функції та передайте їй 5.5 як значення аргументу. Це викличе тестову функцію, яка приймає аргумент float, тобто другу тестову функцію.
  15. Викличте перевірку функції та передайте їй п’ять як значення аргументу. Це викличе тестову функцію, яка приймає символьний аргумент, тобто третю тестову функцію.
  16. Програма має повернути значення, якщо вона працює успішно.
  17. Кінець тіла функції main().

У нас є три функції з однаковою назвою, але різними типами аргументів. Ми досягли поліморфізму.

Operator Перевантаження

In Operator Перевантаження, ми визначаємо нове значення для a C++ оператор. Це також змінює роботу оператора. Наприклад, ми можемо визначити оператор + для об’єднання двох рядків. Ми знаємо його як оператор додавання для додавання числових значень. Після нашого визначення, якщо розмістити між цілими числами, він додасть їх. Якщо розмістити між рядками, він об’єднає їх.

Приклад 2

#include<iostream> 
using namespace std;

class ComplexNum {
private:
	int real, over;
public:
	ComplexNum(int rl = 0, int ov = 0) {
		real = rl;   
		over = ov; 
	}

	ComplexNum operator + (ComplexNum const &obj) {
		ComplexNum result;
		result.real = real + obj.real;
		result.over = over + obj.over;
		return result;
	}
	void print() { 
		cout << real << " + i" << over << endl; 
	}
};
int main()
{
	ComplexNum c1(10, 2), c2(3, 7);
	ComplexNum c3 = c1+c2;
	c3.print();
}

вихід:

Operator Перевантаження

Ось скріншот коду:

Operator Перевантаження

Operator Перевантаження

Пояснення коду:

  1. Включіть файл заголовка iostream у нашу програму, щоб використовувати її функції.
  2. Включіть простір імен std у нашу програму, щоб використовувати його класи без його виклику.
  3. Створіть клас під назвою ComplexNum. { позначає початок тіла класу.
  4. Використовуйте модифікатор приватного доступу, щоб позначити змінні як приватні, тобто до них можна отримати доступ лише з класу.
  5. Визначте дві цілі змінні, дійсну та над.
  6. Використовуйте модифікатор публічного доступу, щоб позначити конструктор як публічний, тобто він буде доступний навіть ззовні клас.
  7. Створіть конструктор класу та ініціалізуйте змінні.
  8. Ініціалізуйте значення змінної real.
  9. Ініціалізація значення змінної over.
  10. Кінець корпусу конструктора.
  11. Нам потрібно перевизначити значення оператора +.
  12. Створіть результат типу даних типу ComplexNum.
  13. Використовуйте оператор + із комплексними числами. Цей рядок додасть дійсну частину числа до дійсної частини іншого числа.
  14. Використовуйте оператор + із комплексними числами. Цей рядок додасть уявну частину числа до уявної частини іншого числа.
  15. Програма поверне значення змінної результат після успішного виконання.
  16. Кінець визначення нового значення оператора +, тобто перевантаження.
  17. Викличте метод print().
  18. Виведіть нове комплексне число після додавання на консолі.
  19. Кінець тіла функції print().
  20. Кінець тіла класу ComplexNum.
  21. Виклик функції main().
  22. Передайте значення як дійсних, так і комплексних частин, які потрібно додати. Перша частина c1 буде додана до першої частини c2, тобто 10+3. Друга частина c1 буде додана до другої частини c, тобто 2+7.
  23. Виконайте операцію за допомогою перевантаженого оператора + і збережіть результат у змінній c3.
  24. Вивести значення змінної c3 на консоль.
  25. Кінець тіла функції main().

Поліморфізм часу виконання

Це трапляється, коли метод об’єкта викликається під час виконання, а не під час компіляції. Поліморфізм виконання досягається за допомогою перевизначення функції. Функція для виклику/виклику встановлюється під час виконання.

Перевизначення функції

Перевизначення функції відбувається, коли функція базового класу отримує нове визначення в похідному класі. У той час ми можемо сказати, що базова функція була перевизначена.

Наприклад:

#include <iostream>
using namespace std;
class Mammal {

public:
	void eat() {

		cout << "Mammals eat...";
	}

};

class Cow: public Mammal {

public:
	void eat() {

		cout << "Cows eat grass...";
	}
};
int main(void) {

	Cow c = Cow();

	c.eat();

	return 0;

}

вихід:

Перевизначення функції

Ось скріншот коду:

Перевизначення функції

Пояснення коду:

  1. Імпортуйте файл заголовка iostream у нашу програму, щоб використовувати її функції.
  2. Включіть простір імен std у нашу програму, щоб використовувати його класи без його виклику.
  3. Створіть клас під назвою «Ссавець». { позначає початок тіла класу.
  4. Використовуйте модифікатор публічного доступу, щоб установити функцію, яку ми збираємось створити, як загальнодоступну. Він буде доступний поза цим класом.
  5. Створіть публічну функцію під назвою «їсти». { позначає початок тіла функції.
  6. Вивести оператор, доданий до функції cout під час виклику функції eat().
  7. Кінець тіла функції eat().
  8. Кінець тіла класу Ссавці.
  9. Створіть клас під назвою Cow, який успадковує клас Mammal. Корова є похідним класом, тоді як Ссавець є базовим класом. { позначає початок цього класу.
  10. Використовуйте модифікатор публічного доступу, щоб позначити функцію, яку ми збираємось створити, як загальнодоступну. Він буде доступний поза цим класом.
  11. Перевизначити функцію eat(), визначену в базовому класі. { позначає початок тіла функції.
  12. Інструкція для друку на консолі під час виклику цієї функції.
  13. Кінець тіла функції eat().
  14. Кінець тіла класу Корова.
  15. Виклик функції main(). { позначає початок тіла цієї функції.
  16. Створіть екземпляр класу Cow і назвіть його c.
  17. Викличте функцію eat(), визначену в класі Cow.
  18. Після успішного завершення програма повинна повернути значення.
  19. Кінець функції main().

C++ Віртуальна функція

Віртуальна функція — це інший спосіб реалізації поліморфізму під час виконання C++. Це спеціальна функція, визначена в базовому класі та перевизначена в похідному класі. Щоб оголосити віртуальну функцію, ви повинні використовувати ключове слово virtual. Ключове слово має передувати оголошенню функції в базовому класі.

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

#include <iostream>  
using namespace std;
class ClassA {
		public:
		virtual void show() {
			cout << "The show() function in base class invoked..." << endl;
		}
	};
	class ClassB :public ClassA {
	public:
		void show() 	{
			cout << "The show() function in derived class invoked...";
		}
	};
	int main() {
		ClassA* a;   
		ClassB b;
		a = &b;
		a->show();      
	}

вихід:

C++ Віртуальна функція

Ось скріншот коду:

C++ Віртуальна функція

Пояснення коду:

  1. Включіть файл заголовка iostream у код, щоб використовувати його функції.
  2. Включіть простір імен std у наш код, щоб використовувати його класи без його виклику.
  3. Створіть клас під назвою ClassA.
  4. Використовуйте модифікатор публічного доступу, щоб позначити члена класу як загальнодоступного.
  5. Створіть віртуальну функцію під назвою show(). Це буде публічна функція.
  6. Текст для друку під час виклику show(). Endl - це a C++ ключове слово, що означає кінцевий рядок. Він переміщує курсор миші на наступний рядок.
  7. Кінець тіла віртуальної функції show().
  8. Кінець тіла класу ClassA.
  9. Створення нового класу з іменем ClassB, який успадковує клас ClassA. ClassA стає базовим класом, а ClassB стає похідним класом.
  10. Використовуйте модифікатор публічного доступу, щоб позначити члена класу як загальнодоступного.
  11. Перевизначте віртуальну функцію show(), отриману в базовому класі.
  12. Текст для друку на консолі під час виклику функції show(), визначеної в похідному класі.
  13. Кінець тіла функції show().
  14. Кінець тіла похідного класу, ClassB.
  15. Виклик функції main(). Логіку програми слід додати в її тіло.
  16. Створіть змінну-вказівник з іменем a. Він вказує на клас під назвою ClassA.
  17. Створіть екземпляр класу з іменем ClassB. Екземпляр отримав назву b.
  18. Призначте значення, що зберігаються за адресою b, у змінну a.
  19. Викликати функцію show(), визначену в похідному класі. Реалізовано пізнє зв’язування.
  20. Кінець тіла функції main().

Поліморфізм під час компіляції Vs. Поліморфізм під час виконання

Ось основні відмінності між ними:

Поліморфізм компіляційного часу Поліморфізм часу виконання
Його також називають раннім зв’язуванням або статичним поліморфізмом Його також називають пізнім/динамічним зв’язуванням або динамічним поліморфізмом
Метод викликається під час компіляції Метод викликається під час виконання
Реалізовано через перевантаження функцій і перевантаження операторів Реалізовано за допомогою перевизначення методів і віртуальних функцій
Приклад, перевантаження методу. Багато методів можуть мати подібні назви, але різну кількість або типи аргументів Приклад, перевизначення методу. Багато методів можуть мати однакові назви та однаковий прототип.
Швидше виконання, оскільки виявлення методів здійснюється під час компіляції Повільніше виконання, оскільки пошук методів виконується під час виконання.
Less забезпечується гнучкість для вирішення проблем, оскільки все відомо під час компіляції. Надається велика гнучкість для вирішення складних проблем, оскільки методи виявляються під час виконання.

Підсумки

  • Поліморфізм означає мати багато форм.
  • Це відбувається, коли існує ієрархія класів, пов’язаних через успадкування.
  • З поліморфізмом функція може поводитися по-різному в залежності від об’єкта, який її викликає.
  • У поліморфізмі під час компіляції функція, яку потрібно викликати, встановлюється під час компіляції.
  • У поліморфізмі середовища виконання функція, яку потрібно викликати, встановлюється під час виконання.
  • Поліморфізм під час компіляції визначається через перевантаження функцій і операторів.
  • У перевантаженні функцій є багато функцій зі схожими назвами, але різними аргументами.
  • Параметри можуть відрізнятися за кількістю або типом.
  • У перевантаженні оператора визначається нове значення для C++ Оператори.
  • Поліморфізм виконання досягається за допомогою перевизначення функції.
  • У перевизначенні функції похідний клас дає нове визначення функції, визначеній у базовому класі.