polymorphism c
Роля на полиморфизма в C ++ с примери.
Полиморфизмът е един от четирите стълба на обектно-ориентираното програмиране. Полиморфизмът означава да има много форми. Може да се определи като техника, чрез която даден обект може да приеме много форми в зависимост от ситуацията.
По отношение на програмирането можем да кажем, че обектът може да се държи по различен начин при различни условия.
В този урок ще научим подробно за видовете полиморфизъм, начините за прилагане на полиморфизма заедно с различните други концепции за полиморфизъм.
=> Проверете тук, за да видите A-Z на C ++ уроци за обучение тук.
Например, жената може да поеме много роли в различни ситуации. За дете тя е майка, домакиня у дома, работник в офиса и т.н. Така че жената поема различни роли и проявява различно поведение при различни условия. Това е реален пример за полиморфизъм.
По същия начин и в света на програмирането можем да имаме оператор „+“, който е двоичният оператор за събиране, който се държи различно, когато операндите се променят. Например, когато двата операнда са числови, той извършва добавяне.
От друга страна, когато операндите са низ, той действа като оператор за конкатенация. По този начин полиморфизмът накратко означава образувание, което приема много форми или се държи по различен начин при различни условия.
Какво ще научите:
- Видове полиморфизъм
- Compile Time Polymorphism Vs. Полиморфизъм по време на изпълнение
- Компилирайте времевия полиморфизъм
- Претоварване на функцията
- Претоварване на оператора
- Заключение
- Препоръчително четене
Видове полиморфизъм
Полиморфизмът се разделя на два вида.
- Компилирайте времевия полиморфизъм
- Полиморфизъм по време на изпълнение
Диаграмата, която представя това е показана по-долу:
как да отворите файлове с
Както е показано в горната диаграма, полиморфизмът е разделен на полиморфизъм по време на компилация и полиморфизъм по време на изпълнение. Полиморфизмът на времето за компилация се разделя допълнително на претоварване на оператора и претоварване на функциите. Полиморфизмът по време на изпълнение се прилага по-нататък с помощта на виртуални функции.
Компилираният времеви полиморфизъм е известен също като ранен обвързващ или статичен полиморфизъм. При този тип полиморфизъм методът на обекта се извиква по време на компилиране. В случай на полиморфизъм по време на изпълнение, методът на обекта се извиква по време на изпълнение.
Полиморфизмът по време на работа е известен също като динамичен или късен свързващ или динамичен полиморфизъм. Ще разгледаме подробно изпълнението на всяка от тези техники в следващите ни теми.
Compile Time Polymorphism Vs. Полиморфизъм по време на изпълнение
Нека видим основните разлики между времето на компилация и полиморфизма по време на изпълнение по-долу.
Компилирайте времевия полиморфизъм | Полиморфизъм по време на изпълнение |
---|---|
Известен също като статичен полиморфизъм или ранно свързване | Известен също като динамичен полиморфизъм или късно / динамично свързване |
Обектният метод се извиква по време на компилация | Методът на обекта се извиква по време на изпълнение |
Обикновено се изпълнява с помощта на претоварване на оператора и претоварване на функции | Реализирано с използване на виртуални функции и заместване на метода |
Претоварването на метода е полиморфизъм по време на компилация, при който повече от един метод може да има едно и също име, но различен списък и типове параметри. | Заменянето на метода е полиморфизъм по време на изпълнение, където повече от един метод има едно и също име с един и същ прототип |
Тъй като методите са известни по време на компилация, изпълнението е по-бързо | Изпълнението е по-бавно, тъй като методът е известен по време на изпълнение |
Осигурете по-малко гъвкавост за внедряване на решения, тъй като всичко трябва да се знае по време на компилиране | Далеч по-гъвкави за прилагане на сложни решения, тъй като методите се решават по време на изпълнение |
Компилирайте времевия полиморфизъм
Полиморфизмът на времето за компилация е техника, при която методът на обекта се извиква по време на компилацията.
Този тип полиморфизъм се реализира по два начина.
- Претоварване на функцията
- Претоварване на оператора
Ще обсъдим подробно всяка техника.
Претоварване на функцията
Казва се, че една функция е претоварена, когато имаме повече от една функция с едно и също име, но различни типове параметри или различен брой аргументи.
По този начин една функция може да бъде претоварена въз основа на типовете параметри, реда на параметрите и броя на параметрите.
Имайте предвид, че две функции с едно и също име и един и същ списък с параметри, но различен тип връщане не са претоварени функции и ще доведат до грешка при компилация, ако се използват в програмата.
По същия начин, когато параметрите на функцията се различават само по указател и ако типът на масива е еквивалентен, тогава той не трябва да се използва за претоварване.
Други типове като статични и нестатични, const и volatile и т.н. Или декларациите на параметри, които се различават по наличие или липса на стойности по подразбиране, също не трябва да се използват за претоварване, тъй като са еквивалентни от гледна точка на изпълнението.
Например,следните прототипи на функции са претоварени функции.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
В горните прототипи виждаме, че претоварваме функцията Add въз основа на типа параметри, последователност или ред на параметрите, брой параметри и т.н.
Нека вземем пълен пример за програмиране, за да разберем по-добре претоварването на функциите.
#include #include using namespace std; class Summation { public: int Add(int num1,int num2) { return num1+num2; } int Add(int num1,int num2, int num3) { return num1+num2+num3; } string Add(string s1,string s2){ return s1+s2; } }; int main(void) { Summation obj; cout< Изход:
35
191
19.
Здравей свят
В горната програма имаме клас Summation, който дефинира три претоварени функции, наречени Add, които вземат два целочислени аргумента, три целочислени аргумента и два низови аргумента.
В основната функция правим четири извиквания на функции, които предоставят различни параметри. Първите две извиквания на функции са ясни. В третото извикване на функцията за добавяне предоставяме две стойности с плаваща запетая като аргументи.
В този случай функцията, която е съпоставена, е int Add (int, int), тъй като вътрешно, поплавъкът се преобразува в double и след това се съчетава с функцията с параметрите int. Ако бяхме посочили double вместо float, тогава щяхме да имаме друга претоварена функция с double като параметри.
Последното извикване на функция използва низови стойности като параметри. В този случай операторът Add (+) действа като оператор за конкатенация и обединява двете низови стойности, за да генерира единичен низ.
Предимства на претоварването на функциите
Основната полза от претоварването на функцията е, че насърчава повторната употреба на кода. Можем да имаме възможно най-много функции с едно и също име, стига те да са претоварени въз основа на типа аргументи, последователността на аргументите и броя на аргументите.
По този начин става по-лесно да имате различни функции с едно и също име, които да представят поведението на една и съща операция при различни условия.
Ако не беше налице претоварване на функции, тогава щеше да се наложи да напишем твърде много различни видове функции с различни имена, като по този начин кодът стане нечетим и труден за адаптиране.
Претоварване на оператора
Претоварването на оператора е техниката, с която придаваме различно значение на съществуващите оператори в C ++. С други думи, претоварваме операторите, за да придадем специално значение на дефинираните от потребителя типове данни като обекти.
Повечето оператори в C ++ са претоварени или им е дадено специално значение, за да могат да работят върху дефинирани от потребителя типове данни. Имайте предвид, че докато се претоварва, основната операция на операторите не се променя. Претоварването просто дава на оператора допълнително значение, като запазва основната им семантика същата.
Въпреки че повечето оператори могат да бъдат претоварени в C ++, има някои оператори, които не могат да бъдат претоварени.
Тези оператори са изброени в таблицата по-долу.
Оператори Оператор за разделителна способност на обхвата (: :) Размер на член за избор (.) член селектор на указател (*) троичен оператор (? :)
Функциите, които използваме за претоварване на операторите, се наричат „ Функции на оператора ”.
Операторските функции са подобни на нормалните функции, но с разлика. Разликата е, че името на операторските функции започва с ключовата дума „ оператор ”, Последвано от символа на оператора, който трябва да бъде претоварен.
След това се извиква операторската функция, когато съответният оператор се използва в програмата. Тези операторски функции могат да бъдат членски функции или глобални методи или дори приятелска функция.
Общият синтаксис на операторската функция е:
return_type classname::operator op(parameter list) { //function body }
Тук “оператор op” е операторската функция, където операторът е ключовата дума, а op е операторът, който трябва да бъде претоварен. Return_type е типът стойност, който трябва да бъде върнат.
Нека видим няколко примера за програмиране, за да демонстрираме претоварване на оператора с помощта на операторски функции.
Пример 1:Претоварване на унарния оператор с помощта на член операторска функция.
#include using namespace std; class Distance { public: int feet; // Constructor to initialize the object's value Distance(int feet) { this->feet = feet; } //operator function to overload ++ operator to perform increment on Distance obj void operator++() { feet++; } void print(){ cout << '
Incremented Feet value: ' << feet; } }; int main() { Distance d1(9); // Use (++) unary operator ++d1; d1.print(); return 0; }
Изход:
Увеличена стойност на краката: 10
Тук сме претоварили унарния оператор на инкремент, използвайки функцията operator ++. В основната функция използваме този оператор ++, за да увеличим обекта от клас Distance.
Пример 2:Претоварване на двоичния оператор с помощта на функцията член оператор.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //Operator function to overload binary + to add two complex numbers Complex operator + (Complex const &obj) { Complex c3; c3.real = real + obj.real; c3.imag = imag + obj.imag; return c3; } void print() { cout << real << ' + i' << imag << endl; } }; int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
Изход:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Тук използвахме класическия пример за добавяне на две комплексни числа с помощта на претоварване на оператора. Определяме клас за представяне на Комплексни числа и операторна функция за претоварване + оператор, в която добавяме реалните и въображаемите части на комплексните числа.
В основната функция декларираме два сложни обекта и ги добавяме с помощта на претоварения + оператор, за да получим желания резултат.
В примера по-долу ще използваме функцията за приятелство, за да добавим две комплексни числа, за да видим разликата в изпълнението.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //friend function to overload binary + to add two complex numbers friend Complex operator +(Complex const &, Complex const &); void print() { cout << real << ' + i' << imag << endl; } }; Complex operator + (Complex const &c1, Complex const &c2) { Complex c3; c3.real = c1.real + c2.real; c3.imag = c1.imag + c2.imag; return c3; } int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
Изход:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
Виждаме, че изходът на програмата е същият. Единствената разлика в реализацията е използването на функция friend за претоварване на оператора + вместо функция член в предишното изпълнение.
Когато за двоичен оператор се използва функция приятел, трябва изрично да посочим и операндите към функцията. По същия начин, когато унарният оператор е претоварен с помощта на приятелска функция, трябва да предоставим единичния операнд на функцията.
Освен функциите на оператора, можем да напишем и оператор за преобразуване който се използва за преобразуване от един тип в друг. Тези претоварени оператори за преобразуване трябва да бъдат член функция на класа.
Пример 3:Претоварване на оператора с помощта на оператор за преобразуване.
#include using namespace std; class DecFraction { int numerator, denom; public: DecFraction(int num, int denm) { numerator = num; denom = denm; } // conversion operator: converts fraction to float value and returns it operator float() const { return float(numerator) / float(denom); } }; int main() { DecFraction df(3, 5); //object of class float res_val = df; //calls conversion operator cout << 'The resultant value of given fraction (3,5)= '< Изход:
Получената стойност на дадена фракция (3,5) = 0,6
В тази програма сме използвали оператора за преобразуване, за да преобразуваме дадената фракция в плаваща стойност. След като преобразуването приключи, операторът за преобразуване връща получената стойност на повикващия.
В основната функция, когато присвояваме обекта df на променлива res_val, преобразуването се извършва и резултатът се съхранява в res_val.
Също така можем да извикаме конструктор с един аргумент. Когато можем да извикаме конструктор от класа с помощта на един аргумент, това се нарича „ конверсия строител ”. Конструктор на преобразуване може да се използва за имплицитно преобразуване в класа, който се конструира.
#include using namespace std; class Point { private: int x,y; public: Point(int i=0,int j=0) {x = i;y=j;} void print() { cout<<' x = '< Изход:
Точка, конструирана с помощта на нормален конструктор
x = 20 y = 30
Точка, конструирана с помощта на конструктор за преобразуване
x = 10 y = 0

Тук имаме клас Point, който дефинира конструктор със стойности по подразбиране. В основната функция конструираме обект pt с координати x и y. След това просто присвояваме на pt стойност 10. Това е мястото, където се извиква конструкторът на преобразуване и на x се присвоява стойност 10, докато на y се дава стойност по подразбиране 0.
Правила за претоварване на оператора
Докато извършваме претоварване на оператора, трябва да внимаваме за правилата по-долу.
- В C ++ сме в състояние да претоварим само съществуващите оператори. Новодобавените оператори не могат да бъдат претоварени.
- Когато операторите са претоварени, трябва да гарантираме, че поне един от операндите е от потребителски дефиниран тип.
- За да претоварим определени оператори, можем да използваме и функцията за приятели.
- Когато претоварваме унарни оператори, използвайки функция член, тя не взема изрични аргументи. Отнема един изричен аргумент, когато унарният оператор е претоварен с помощта на приятелска функция.
- По същия начин, когато двоичните оператори са претоварени с помощта на член-функция, ние трябва да предоставим един изричен аргумент на функцията. Когато двоичните оператори са претоварени с помощта на приятелска функция, функцията взема два аргумента.
- В C ++ има два оператора, които вече са претоварени. Това са „=” и „&”. Следователно, за да копираме обект от същия клас, не е необходимо да претоварваме оператора = и можем да го използваме директно.
Предимства на претоварването на оператора
Претоварването на оператора в C ++ ни позволява да разширим функционалността на операторите до дефинираните от потребителя типове, включително обекти на класа в допълнение към вградените типове.
Разширявайки функционалността на оператора до дефинираните от потребителя типове, не е необходимо да пишем сложен код, за да изпълняваме различни операции върху дефинирани от потребителя типове, но можем да го направим в една операция, точно като вградените типове.
Заключение
Компилираният времеви полиморфизъм осигурява съоръжение за претоварване главно за разширяване на функционалността на кода по отношение на претоварване на функциите и претоварване на оператора.
Чрез претоварване на функцията можем да напишем повече от една функция с едно и също име, но различни параметри и типове. Това прави кода прост и лесно четим. Чрез претоварване на оператора можем да разширим функционалността на операторите, така че да можем да правим основни операции и на дефинирани от потребителя типове.
В нашия предстоящ урок ще научим повече за полиморфизма по време на изпълнение в C ++.
=> Прочетете серията Easy C ++ Training.
Препоръчително четене
- Полиморфизъм по време на изпълнение в C ++
- Приятелски функции в C ++
- Рекурсия в C ++
- Урок за основната функция на Python с практически примери
- Пълен преглед на C ++
- Урок за QTP # 21 - Как да направим QTP тестове модулни и многократно използващи библиотеки с действия и функции
- Урок за Unix Pipes: Тръби в програмирането на Unix
- Библиотечни функции в C ++