C++ Polimorfism cu Exemplu

รŽn ce este polimorfismul C++?

In C++, polimorfismul face ca o funcศ›ie membru sฤƒ se comporte diferit รฎn funcศ›ie de obiectul care o apeleazฤƒ/invocฤƒ. Polimorfismul este un cuvรขnt grecesc care รฎnseamnฤƒ a avea mai multe forme. Apare atunci cรขnd aveศ›i o ierarhie de clase legate prin moศ™tenire.

De exemplu, sฤƒ presupunem cฤƒ avem funcศ›ia makeSound(). Cรขnd o pisicฤƒ apeleazฤƒ aceastฤƒ funcศ›ie, va produce sunetul miau. Atunci cรขnd o vacฤƒ invocฤƒ aceeaศ™i funcศ›ie, va furniza sunetul de cosuit.

 Polimorfismul รฎn C++

Deศ™i avem o singurฤƒ funcศ›ie, aceasta se comportฤƒ diferit รฎn diferite circumstanศ›e. Funcศ›ia are multe forme; prin urmare, am atins polimorfismul.

Tipuri de polimorfism

C++ suportฤƒ douฤƒ tipuri de polimorfism:

  • polimorfism รฎn timp de compilare ศ™i
  • Polimorfismul runtime.

Tipuri de polimorfism

Polimorfismul timpului de compilare

Invocaศ›i funcศ›iile supraรฎncฤƒrcate prin potrivirea numฤƒrului ศ™i tipului de argumente. Informaศ›iile sunt prezente รฎn timpul compilฤƒrii. Aceasta รฎnseamnฤƒ C++ compilatorul va selecta funcศ›ia potrivitฤƒ รฎn timpul compilฤƒrii.

Polimorfismul รฎn timp de compilare se realizeazฤƒ prin supraรฎncฤƒrcarea funcศ›iilor ศ™i supraรฎncฤƒrcarea operatorului.

Supraรฎncฤƒrcarea funcศ›iei

Supraรฎncฤƒrcarea funcศ›iilor apare atunci cรขnd avem multe funcศ›ii cu nume similare, dar cu argumente diferite. Argumentele pot diferi รฎn ceea ce priveศ™te numฤƒrul sau tipul.

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

ieศ™ire:

Supraรฎncฤƒrcarea funcศ›iei

Iatฤƒ o capturฤƒ de ecran a codului:

Supraรฎncฤƒrcarea funcศ›iei

Explicaศ›ia codului:

  1. Includeศ›i fiศ™ierul antet iostream รฎn codul nostru. Vom putea folosi funcศ›iile sale.
  2. Includeศ›i spaศ›iul de nume std รฎn codul nostru. Vom putea folosi clasele sale fฤƒrฤƒ a-l apela.
  3. Creaศ›i o funcศ›ie numitฤƒ test care ia un parametru รฎntreg i. { marcheazฤƒ รฎnceputul corpului testului funcศ›ional.
  4. Declaraศ›ie care trebuie executatฤƒ dacฤƒ testul funcศ›iei de mai sus este invocat/apelat.
  5. Sfรขrศ™itul corpului testului funcศ›ional de mai sus.
  6. Creaศ›i o funcศ›ie numitฤƒ test care ia un parametru float f. { marcheazฤƒ รฎnceputul corpului testului funcศ›ional.
  7. Declaraศ›ie care trebuie executatฤƒ dacฤƒ testul funcศ›iei de mai sus este invocat/apelat.
  8. Sfรขrศ™itul corpului testului funcศ›ional de mai sus.
  9. Creaศ›i o funcศ›ie numitฤƒ test care ia un parametru de caracter ch. { marcheazฤƒ รฎnceputul corpului testului funcศ›ional.
  10. Declaraศ›ie care trebuie executatฤƒ dacฤƒ testul funcศ›iei de mai sus este invocat/apelat.
  11. Sfรขrศ™itul corpului testului funcศ›ional de mai sus.
  12. Apelaศ›i funcศ›ia main(). { marcheazฤƒ รฎnceputul corpului funcศ›iei.
  13. Apelaศ›i testul funcศ›iei ศ™i treceศ›i-i 5 ca valoare a argumentului. Aceasta invocฤƒ funcศ›ia de testare care acceptฤƒ un argument รฎntreg, adicฤƒ prima funcศ›ie de testare.
  14. Apelaศ›i testul funcศ›iei ศ™i treceศ›i-i 5.5 ca valoare a argumentului. Aceasta va invoca funcศ›ia de testare care acceptฤƒ un argument flotant, adicฤƒ a doua funcศ›ie de testare.
  15. Apelaศ›i testul funcศ›iei ศ™i treceศ›i-i cinci ca valoare a argumentului. Aceasta va invoca funcศ›ia de testare care acceptฤƒ un argument caracter, adicฤƒ a treia funcศ›ie de testare.
  16. Programul trebuie sฤƒ returneze o valoare dacฤƒ ruleazฤƒ cu succes.
  17. Sfรขrศ™itul corpului funcศ›iei main().

Avem trei funcศ›ii cu acelaศ™i nume, dar diferite tipuri de argumente. Am atins polimorfismul.

Operator Supraรฎncฤƒrcare

In Operator Supraรฎncฤƒrcare, definim un nou sens pentru a C++ operator. De asemenea, schimbฤƒ modul รฎn care lucreazฤƒ operatorul. De exemplu, putem defini operatorul + pentru a concatena douฤƒ ศ™iruri. รŽl ศ™tim ca operator de adunare pentru adฤƒugarea de valori numerice. Dupฤƒ definiศ›ia noastrฤƒ, atunci cรขnd este plasat รฎntre numere รฎntregi, le va adฤƒuga. Cรขnd este plasat รฎntre ศ™iruri, le va concatena.

Exemplu 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();
}

ieศ™ire:

Operator Supraรฎncฤƒrcare

Iatฤƒ o capturฤƒ de ecran a codului:

Operator Supraรฎncฤƒrcare

Operator Supraรฎncฤƒrcare

Explicaศ›ia codului:

  1. Includeศ›i fiศ™ierul antet iostream รฎn programul nostru pentru a utiliza funcศ›iile acestuia.
  2. Includeศ›i spaศ›iul de nume std รฎn programul nostru pentru a utiliza clasele sale fฤƒrฤƒ a-l apela.
  3. Creaศ›i o clasฤƒ numitฤƒ ComplexNum. { marcheazฤƒ รฎnceputul corpului clasei.
  4. Utilizaศ›i modificatorul de acces privat pentru a marca variabilele ca private, ceea ce รฎnseamnฤƒ cฤƒ pot fi accesate numai din cadrul clasei.
  5. Definiศ›i douฤƒ variabile รฎntregi, reale ศ™i peste.
  6. Utilizaศ›i modificatorul de acces public pentru a marca constructorul ca public, ceea ce รฎnseamnฤƒ cฤƒ va fi accesibil chiar ศ™i din afara clasฤƒ.
  7. Creaศ›i constructorul clasei ศ™i iniศ›ializaศ›i variabilele.
  8. Iniศ›ializaศ›i valoarea variabilei real.
  9. Iniศ›ializaศ›i valoarea variabilei peste.
  10. Sfรขrศ™itul corpului constructorului.
  11. Trebuie sฤƒ suprascriem semnificaศ›ia operatorului +.
  12. Creaศ›i rezultatul tipului de date de tip ComplexNum.
  13. Utilizaศ›i operatorul + cu numere complexe. Aceastฤƒ linie va adฤƒuga partea realฤƒ a unui numฤƒr la partea realฤƒ a altui numฤƒr.
  14. Utilizaศ›i operatorul + cu numere complexe. Aceastฤƒ linie va adฤƒuga partea imaginarฤƒ a unui numฤƒr la partea imaginarฤƒ a altui numฤƒr.
  15. Programul va returna valoarea rezultatului variabilei la executarea cu succes.
  16. Sfรขrศ™itul definiศ›iei noului sens al operatorului +, adicฤƒ supraรฎncฤƒrcarea.
  17. Apelaศ›i metoda print().
  18. Tipฤƒriศ›i noul numฤƒr complex dupฤƒ adฤƒugare pe consolฤƒ.
  19. Sfรขrศ™itul corpului funcศ›iei print().
  20. Sfรขrศ™itul corpului clasei ComplexNum.
  21. Apelaศ›i funcศ›ia main().
  22. Transmiteศ›i valorile atรขt ale pฤƒrศ›ilor reale, cรขt ศ™i ale pฤƒrศ›ilor complexe care urmeazฤƒ sฤƒ fie adฤƒugate. Prima parte a lui c1 va fi adฤƒugatฤƒ la prima parte a lui c2, adicฤƒ 10+3. A doua parte a lui c1 va fi adฤƒugatฤƒ la a doua parte a lui c, adicฤƒ 2+7.
  23. Efectuaศ›i o operaศ›ie folosind operatorul supraรฎncฤƒrcat + ศ™i stocรขnd rezultatul รฎn variabila c3.
  24. Tipฤƒriศ›i valoarea variabilei c3 pe consolฤƒ.
  25. Sfรขrศ™itul corpului funcศ›iei main().

Polimorfismul รฎn timpul rulฤƒrii

Acest lucru se รฎntรขmplฤƒ atunci cรขnd metoda unui obiect este invocatฤƒ/apelatฤƒ รฎn timpul rulฤƒrii, mai degrabฤƒ decรขt รฎn โ€‹โ€‹timpul compilฤƒrii. Polimorfismul runtime se realizeazฤƒ prin suprascrierea funcศ›iei. Funcศ›ia care trebuie apelatฤƒ/invocatฤƒ este stabilitฤƒ รฎn timpul rulฤƒrii.

Suprascrierea funcศ›iei

Suprascrierea funcศ›iei are loc atunci cรขnd unei funcศ›ii a clasei de bazฤƒ i se dฤƒ o nouฤƒ definiศ›ie รฎntr-o clasฤƒ derivatฤƒ. รŽn acel moment, putem spune cฤƒ funcศ›ia de bazฤƒ a fost รฎnlocuitฤƒ.

De exemplu:

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

}

ieศ™ire:

Suprascrierea funcศ›iei

Iatฤƒ o capturฤƒ de ecran a codului:

Suprascrierea funcศ›iei

Explicaศ›ia codului:

  1. Importaศ›i fiศ™ierul antet iostream รฎn programul nostru pentru a utiliza funcศ›iile acestuia.
  2. Includeศ›i spaศ›iul de nume std รฎn programul nostru pentru a utiliza clasele sale fฤƒrฤƒ a-l apela.
  3. Creaศ›i o clasฤƒ numitฤƒ Mamifer. { marcheazฤƒ รฎnceputul corpului clasei.
  4. Utilizaศ›i modificatorul de acces public pentru a seta funcศ›ia pe care urmeazฤƒ sฤƒ o creฤƒm ca fiind accesibilฤƒ publicului. Acesta va fi accesibil din afara acestei clase.
  5. Creaศ›i o funcศ›ie publicฤƒ numitฤƒ eat. { marcheazฤƒ รฎnceputul corpului funcศ›iei.
  6. Imprimaศ›i instrucศ›iunea adฤƒugatฤƒ la funcศ›ia cout cรขnd este invocatฤƒ funcศ›ia eat().
  7. Sfรขrศ™itul corpului funcศ›iei eat().
  8. Sfรขrศ™itul corpului clasei Mamifer.
  9. Creaศ›i o clasฤƒ numitฤƒ Cow care moศ™teneศ™te clasa Mammal. Vaca este clasa derivatฤƒ, รฎn timp ce Mamiferul este clasa de bazฤƒ. { marcheazฤƒ รฎnceputul acestei clase.
  10. Utilizaศ›i modificatorul de acces public pentru a marca funcศ›ia pe care urmeazฤƒ sฤƒ o creฤƒm ca fiind accesibilฤƒ publicului. Acesta va fi accesibil din afara acestei clase.
  11. Ignoraศ›i funcศ›ia eat() care a fost definitฤƒ รฎn clasa de bazฤƒ. { marcheazฤƒ รฎnceputul corpului funcศ›iei.
  12. Declaraศ›ia de tipฤƒrit pe consolฤƒ atunci cรขnd aceastฤƒ funcศ›ie este invocatฤƒ.
  13. Sfรขrศ™itul corpului funcศ›iei eat().
  14. Sfรขrศ™itul corpului clasei Vaca.
  15. Apelaศ›i funcศ›ia main(). { marcheazฤƒ รฎnceputul corpului acestei funcศ›ii.
  16. Creaศ›i o instanศ›ฤƒ a clasei Cow ศ™i dรขndu-i numele c.
  17. Apelaศ›i funcศ›ia eat() definitฤƒ รฎn clasa Cow.
  18. Programul trebuie sฤƒ returneze o valoare la finalizarea cu succes.
  19. Sfรขrศ™itul funcศ›iei main().

C++ Funcศ›ia virtualฤƒ

O funcศ›ie virtualฤƒ este o altฤƒ modalitate de implementare a polimorfismului รฎn timp de rulare รฎn C++. Este o funcศ›ie specialฤƒ definitฤƒ รฎntr-o clasฤƒ de bazฤƒ ศ™i redefinitฤƒ รฎn clasa derivatฤƒ. Pentru a declara o funcศ›ie virtualฤƒ, ar trebui sฤƒ utilizaศ›i cuvรขntul cheie virtual. Cuvรขntul cheie ar trebui sฤƒ preceadฤƒ declararea funcศ›iei รฎn clasa de bazฤƒ.

Dacฤƒ o clasฤƒ de funcศ›ie virtualฤƒ este moศ™tenitฤƒ, clasa virtualฤƒ redefineศ™te funcศ›ia virtualฤƒ pentru a se potrivi nevoilor sale. De exemplu:

#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();      
	}

ieศ™ire:

C++ Funcศ›ia virtualฤƒ

Iatฤƒ o capturฤƒ de ecran a codului:

C++ Funcศ›ia virtualฤƒ

Explicaศ›ia codului:

  1. Includeศ›i fiศ™ierul antet iostream รฎn cod pentru a utiliza funcศ›iile acestuia.
  2. Includeศ›i spaศ›iul de nume std รฎn codul nostru pentru a-i folosi clasele fฤƒrฤƒ a-l apela.
  3. Creaศ›i o clasฤƒ numitฤƒ ClassA.
  4. Utilizaศ›i modificatorul de acces public pentru a marca un membru al clasei ca fiind accesibil public.
  5. Creaศ›i o funcศ›ie virtualฤƒ numitฤƒ show(). Va fi o funcศ›ie publicฤƒ.
  6. Textul de imprimat atunci cรขnd show() invocat este invocat. Sfรขrศ™itul este a C++ cuvรขnt cheie, care รฎnseamnฤƒ linia finalฤƒ. Mutฤƒ โ€‹โ€‹cursorul mouse-ului pe linia urmฤƒtoare.
  7. Sfรขrศ™itul corpului funcศ›iei virtuale show().
  8. Sfรขrศ™itul corpului clasei ClassA.
  9. Crearea unei noi clase numite ClassB care moศ™teneศ™te clasa ClassA. ClassA devine clasa de bazฤƒ, รฎn timp ce ClassB devine clasa derivatฤƒ.
  10. Utilizaศ›i modificatorul de acces public pentru a marca un membru al clasei ca fiind accesibil public.
  11. Redefiniศ›i funcศ›ia virtualฤƒ show() derivatฤƒ รฎn clasa de bazฤƒ.
  12. Textul de tipฤƒrit pe consolฤƒ cรขnd este invocatฤƒ funcศ›ia show() definitฤƒ รฎn clasa derivatฤƒ.
  13. Sfรขrศ™itul corpului funcศ›iei show().
  14. Sfรขrศ™itul corpului clasei derivate, ClassB.
  15. Apelaศ›i funcศ›ia main(). Logica programului ar trebui adฤƒugatฤƒ รฎn corpul sฤƒu.
  16. Creaศ›i o variabilฤƒ pointer numitฤƒ a. Indicฤƒ clasa numitฤƒ ClassA.
  17. Creaศ›i o instanศ›ฤƒ a clasei numitฤƒ ClassB. Instanศ›a primeศ™te numele b.
  18. Atribuiศ›i stocurile de valori รฎn adresa b รฎn variabila a.
  19. Invocaศ›i funcศ›ia show() definitฤƒ รฎn clasa derivatฤƒ. Legarea tardivฤƒ a fost implementatฤƒ.
  20. Sfรขrศ™itul corpului funcศ›iei main().

Polimorfismul รฎn timp de compilare vs. Polimorfismul รฎn timp de rulare

Iatฤƒ diferenศ›ele majore dintre cele douฤƒ:

Polimorfism รฎn timp de compilare Polimorfismul timpului de rulare
Se mai numeศ™te legare timpurie sau polimorfism static Se mai numeศ™te legare tardivฤƒ/dinamicฤƒ sau polimorfism dinamic
Metoda este apelatฤƒ/invocatฤƒ รฎn timpul compilฤƒrii Metoda este apelatฤƒ/invocatฤƒ รฎn timpul rulฤƒrii
Implementat prin supraรฎncฤƒrcarea funcศ›iilor ศ™i supraรฎncฤƒrcarea operatorului Implementat prin suprascrierea metodei ศ™i funcศ›ii virtuale
De exemplu, supraรฎncฤƒrcarea metodei. Multe metode pot avea nume similare, dar numฤƒr sau tipuri diferite de argumente Exemplu, รฎnlocuirea metodei. Multe metode pot avea un nume similar ศ™i acelaศ™i prototip.
Execuศ›ie mai rapidฤƒ, deoarece descoperirea metodelor se face รฎn timpul compilฤƒrii Execuศ›ie mai lentฤƒ, deoarece metoda de descoperire se face รฎn timpul rulฤƒrii.
Less este oferitฤƒ flexibilitate pentru rezolvarea problemelor, deoarece totul este cunoscut รฎn timpul compilฤƒrii. Este oferitฤƒ multฤƒ flexibilitate pentru rezolvarea problemelor complexe, deoarece metodele sunt descoperite รฎn timpul rulฤƒrii.

Rezumat

  • Polimorfismul รฎnseamnฤƒ a avea mai multe forme.
  • Apare atunci cรขnd existฤƒ o ierarhie a claselor legate prin moศ™tenire.
  • Cu polimorfism, o funcศ›ie se poate comporta diferit รฎn funcศ›ie de obiectul care o invocฤƒ/o chema.
  • รŽn polimorfismul รฎn timp de compilare, funcศ›ia care trebuie invocatฤƒ este stabilitฤƒ รฎn timpul compilฤƒrii.
  • รŽn polimorfismul runtime, funcศ›ia care trebuie invocatฤƒ este stabilitฤƒ รฎn timpul rulฤƒrii.
  • Polimorfismul รฎn timp de compilare este determinat prin supraรฎncฤƒrcarea funcศ›iilor ศ™i supraรฎncฤƒrcarea operatorului.
  • รŽn supraรฎncฤƒrcarea funcศ›iilor, existฤƒ multe funcศ›ii cu nume similare, dar cu argumente diferite.
  • Parametrii pot diferi ca numฤƒr sau tip.
  • รŽn supraรฎncฤƒrcarea operatorului, este definit un nou sens pentru C++ Operatorii.
  • Polimorfismul runtime se realizeazฤƒ prin suprascrierea funcศ›iei.
  • รŽn suprascrierea funcศ›iei, o clasฤƒ derivatฤƒ oferฤƒ o nouฤƒ definiศ›ie unei funcศ›ii definite รฎn clasa de bazฤƒ.

Rezumaศ›i aceastฤƒ postare cu: