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 като стойност на аргумента. Това ще извика тестовата функция, която приема плаващ аргумент, тоест втората тестова функция.
  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. Дефинирайте две целочислени променливи, real и over.
  6. Използвайте модификатора за публичен достъп, за да маркирате конструктора като публичен, което означава, че той ще бъде достъпен дори извън клас.
  7. Създайте конструктора на класа и инициализирайте променливите.
  8. Инициализирайте стойността на променливата real.
  9. Инициализирайте стойността на променливата над.
  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. Създайте клас с име Mammal. { отбелязва началото на тялото на класа.
  4. Използвайте модификатора за публичен достъп, за да зададете функцията, която ще създадем, като публично достъпна. Ще бъде достъпен извън този клас.
  5. Създайте публична функция, наречена яде. { отбелязва началото на тялото на функцията.
  6. Отпечатайте оператора, добавен към функцията cout, когато функцията eat() е извикана.
  7. Краят на тялото на функцията eat().
  8. Край на тялото на клас Бозайник.
  9. Създайте клас с име Крава, който наследява класа Бозайник. Кравата е производният клас, докато бозайникът е базовият клас. { отбелязва началото на този клас.
  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(). Краят е 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 осигурена е гъвкавост за решаване на проблеми, тъй като всичко е известно по време на компилиране. Осигурена е голяма гъвкавост за решаване на сложни проблеми, тъй като методите се откриват по време на изпълнение.

Oбобщение

  • Полиморфизмът означава да има много форми.
  • Това се случва, когато има йерархия от класове, свързани чрез наследяване.
  • С полиморфизма функцията може да се държи различно в зависимост от обекта, който я извиква/извиква.
  • При полиморфизма по време на компилиране, функцията, която трябва да бъде извикана, се установява по време на компилиране.
  • При полиморфизъм по време на изпълнение функцията, която трябва да бъде извикана, се установява по време на изпълнение.
  • Полиморфизмът по време на компилиране се определя чрез претоварване на функции и претоварване на оператори.
  • При претоварване на функции има много функции с подобни имена, но различни аргументи.
  • Параметрите могат да се различават по брой или тип.
  • При претоварване на оператора се дефинира ново значение за C++ оператори.
  • Полиморфизмът по време на изпълнение се постига чрез замяна на функцията.
  • При отмяната на функция, производен клас дава нова дефиниция на функция, дефинирана в основния клас.