C++ Polümorfism näitega
Mis on polümorfism C++?
In C++, põhjustab polümorfism liikmefunktsiooni erineva käitumise olenevalt objektist, mis seda kutsub/välja kutsub. Polümorfism on kreekakeelne sõna, mis tähendab paljude vormide olemasolu. See juhtub siis, kui teil on pärimise kaudu seotud klasside hierarhia.
Oletame näiteks, et meil on funktsioon makeSound(). Kui kass sellele funktsioonile helistab, kostab see mjäu. Kui lehm käivitab sama funktsiooni, annab see niitmise heli.
Kuigi meil on üks funktsioon, käitub see erinevates tingimustes erinevalt. Funktsioonil on palju vorme; seega oleme saavutanud polümorfismi.
Polümorfismi tüübid
C++ toetab kahte tüüpi polümorfismi:
- Koostamise aja polümorfism ja
- Kestusaegne polümorfism.
Aja polümorfismi koostamine
Ülekoormatud funktsioonid kutsutakse esile argumentide arvu ja tüübi sobitamisega. Info on kompileerimise ajal olemas. See tähendab, C++ kompilaator valib kompileerimise ajal õige funktsiooni.
Kompileerimisaja polümorfism saavutatakse funktsioonide ülekoormuse ja operaatori ülekoormuse kaudu.
Funktsiooni ülekoormus
Funktsioonide ülekoormus tekib siis, kui meil on palju sarnase nimega, kuid erinevate argumentidega funktsioone. Argumendid võivad arvu või tüübi poolest erineda.
Näiteks 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;
}
Väljund:
Siin on koodi ekraanipilt:
Koodi selgitus:
- Kaasake iostreami päisefail meie koodi. Saame selle funktsioone kasutada.
- Lisage meie koodi std nimeruum. Saame selle klasse kasutada ilma sellele helistamata.
- Looge funktsioon nimega test, mis võtab täisarvulise parameetri i. { tähistab funktsiooni testi algust.
- Avaldus, mis tuleb täita, kui ülaltoodud funktsiooni test on välja kutsutud/kutsutud.
- Ülaltoodud funktsioonitesti keha lõpp.
- Looge funktsioon nimega test, mis võtab ujuva parameetri f. { tähistab funktsiooni testi algust.
- Avaldus, mis tuleb täita, kui ülaltoodud funktsiooni test on välja kutsutud/kutsutud.
- Ülaltoodud funktsioonitesti keha lõpp.
- Looge funktsioon nimega test, mis võtab märgiparameetri ch. { tähistab funktsiooni testi algust.
- Avaldus, mis tuleb täita, kui ülaltoodud funktsiooni test on välja kutsutud/kutsutud.
- Ülaltoodud funktsioonitesti keha lõpp.
- Kutsuge funktsioon main(). { tähistab funktsiooni keha algust.
- Kutsuge välja funktsiooni test ja andke sellele argumendi väärtuseks 5. See käivitab testfunktsiooni, mis aktsepteerib täisarvu argumendi, st esimese testfunktsiooni.
- Kutsuge välja funktsiooni test ja andke sellele argumendi väärtuseks 5.5. See käivitab testfunktsiooni, mis aktsepteerib ujuva argumendi, st teise testfunktsiooni.
- Kutsuge välja funktsiooni test ja andke sellele argumendi väärtuseks viis. See käivitab testfunktsiooni, mis aktsepteerib märgiargumendi, st kolmanda testfunktsiooni.
- Programm peab tagastama väärtuse, kui see töötab edukalt.
- Funktsiooni main() keha lõpp.
Meil on kolm sama nime, kuid erinevat tüüpi argumentidega funktsiooni. Oleme saavutanud polümorfismi.
Operator Ülekoormus
In Operator Ülekoormamisel määratleme a-le uue tähenduse C++ operaator. See muudab ka seda, kuidas operaator töötab. Näiteks võime määratleda operaatori + kahe stringi ühendamiseks. Teame seda arvuliste väärtuste lisamise operaatorina. Pärast meie määratlust lisab see täisarvude vahele paigutamisel need. Kui see asetatakse stringide vahele, ühendab see need kokku.
Näiteks 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();
}
Väljund:
Siin on koodi ekraanipilt:
Koodi selgitus:
- Kaasake iostreami päisefail meie programmi, et selle funktsioone kasutada.
- Kaasake std nimeruum meie programmi, et kasutada selle klasse ilma seda kutsumata.
- Looge klass nimega ComplexNum. { märgib klassi keha algust.
- Kasutage privaatse juurdepääsu modifikaatorit muutujate privaatseks märkimiseks, mis tähendab, et neile pääseb juurde ainult klassi seest.
- Määratlege kaks täisarvu muutujat, reaalne ja üle.
- Kasutage avaliku juurdepääsu modifikaatorit, et märkida ehitaja avalikuks, mis tähendab, et see on juurdepääsetav isegi väljastpoolt klass.
- Looge klassi konstruktor ja lähtestage muutujad.
- Initsialiseerige muutuja real väärtus.
- Initsialiseerige muutuja väärtus over.
- Konstruktori korpuse lõpp.
- Peame alistama operaatori + tähenduse.
- Looge andmetüübi tulemus tüübiga ComplexNum.
- Kasutage kompleksarvude puhul operaatorit +. See rida lisab arvu reaalosa teise arvu reaalosale.
- Kasutage kompleksarvude puhul operaatorit +. See rida lisab arvu mõttelise osa teise arvu imaginaarsele osale.
- Programm tagastab edukal täitmisel muutuja tulemuse väärtuse.
- Operaatori + uue tähenduse ehk ülekoormamise definitsiooni lõpp.
- Kutsuge print() meetodit.
- Printige uus kompleksarv pärast lisamist konsoolil.
- Funktsiooni print() kehaosa lõpp.
- Klassi ComplexNum keha lõpp.
- Kutsuge funktsioon main().
- Edastage lisatavate reaalsete ja keerukate osade väärtused. C1 esimene osa lisatakse c2 esimesele osale, see tähendab 10+3. C1 teine osa lisatakse c teisele osale, see tähendab 2+7.
- Tehke toiming, kasutades operaatorit overloaded + ja salvestades tulemuse muutujasse c3.
- Printige konsoolile muutuja c3 väärtus.
- Funktsiooni main() keha lõpp.
Käitusaja polümorfism
See juhtub siis, kui objekti meetodit käivitatakse/kutsutakse pigem käitusajal kui kompileerimise ajal. Käitusaegne polümorfism saavutatakse funktsiooni alistamise kaudu. Funktsioon, mida kutsuda/välja kutsuda, määratakse käitusajal.
Funktsiooni alistamine
Funktsiooni alistamine toimub siis, kui põhiklassi funktsioonile antakse tuletatud klassis uus definitsioon. Sel ajal võime öelda, et põhifunktsioon on alistatud.
Näiteks:
#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;
}
Väljund:
Siin on koodi ekraanipilt:
Koodi selgitus:
- Selle funktsioonide kasutamiseks importige iostreami päisefail meie programmi.
- Kaasake std nimeruum meie programmi, et kasutada selle klasse ilma seda kutsumata.
- Looge klass nimega Mammal. { tähistab klassi keha algust.
- Kasutage avaliku juurdepääsu modifikaatorit, et määrata funktsioon, mida loome, avalikult juurdepääsetavaks. See on juurdepääsetav väljaspool seda klassi.
- Looge avalik funktsioon nimega eat. { tähistab funktsiooni keha algust.
- Printige funktsiooni eat() käivitamisel funktsioonile cout lisatud lause.
- Funktsiooni keha lõpp süüa().
- Imetajate klassi keha lõpp.
- Looge klass nimega Cow, mis pärib imetajate klassi. Lehm on tuletatud klass, imetaja aga põhiklass. { tähistab selle klassi algust.
- Kasutage avaliku juurdepääsu modifikaatorit, et märkida funktsioon, mida loome, avalikult juurdepääsetavaks. See on juurdepääsetav väljaspool seda klassi.
- Alistab põhiklassis määratletud funktsiooni eat(). { tähistab funktsiooni keha algust.
- Avaldus, mis prinditakse selle funktsiooni käivitamisel konsoolile.
- Funktsiooni eat() keha lõpp.
- Klassi keha lõpp Lehm.
- Kutsuge funktsioon main(). { märgib selle funktsiooni keha algust.
- Looge Cow klassi eksemplar ja andke sellele nimi c.
- Kutsuge Cow klassis määratletud funktsioon eat().
- Programm peab pärast edukat lõpetamist tagastama väärtuse.
- Funktsiooni main() lõpp.
C++ Virtuaalne funktsioon
Virtuaalne funktsioon on veel üks viis käitusaegse polümorfismi rakendamiseks C++. See on põhiklassis määratletud ja tuletatud klassis uuesti määratletud funktsioon. Virtuaalse funktsiooni deklareerimiseks peaksite kasutama virtuaalset märksõna. Märksõna peaks eelnema funktsiooni deklareerimisele põhiklassis.
Kui virtuaalne funktsiooniklass on päritud, määratleb virtuaalne klass virtuaalse funktsiooni ümber, et see vastaks oma vajadustele. Näiteks:
#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();
}
Väljund:
Siin on koodi ekraanipilt:
Koodi selgitus:
- Selle funktsioonide kasutamiseks lisage koodi iostreami päisefail.
- Lisage meie koodi std nimeruum, et kasutada selle klasse ilma seda kutsumata.
- Looge klass nimega ClassA.
- Kasutage avaliku juurdepääsu muutjat, et märkida klassi liige avalikult juurdepääsetavaks.
- Looge virtuaalne funktsioon nimega show(). Sellest saab avalik funktsioon.
- Tekst, mis prinditakse, kui käivitatakse show() Endl on a C++ märksõna, mis tähendab lõpprida. See viib hiirekursori järgmisele reale.
- Virtuaalse funktsiooni show() keha lõpp.
- Klassi A-klassi keha lõpp.
- Uue klassi loomine nimega ClassB, mis pärib klassi ClassA. Klassist A saab baasklass, klassist B aga tuletatud klass.
- Kasutage avaliku juurdepääsu muutjat, et märkida klassi liige avalikult juurdepääsetavaks.
- Määrake uuesti põhiklassis tuletatud virtuaalne funktsioon show().
- Tekst, mis prinditakse konsoolil, kui käivitatakse tuletatud klassis defineeritud funktsioon show().
- Funktsiooni show() keha lõpp.
- Tuletatud klassi põhiosa lõpp, klass B.
- Kutsuge funktsioon main(). Programmi loogika tuleks lisada selle kehasse.
- Looge kursormuutuja nimega a. See osutab klassile nimega ClassA.
- Looge klassi eksemplar nimega ClassB. Eksemplarile antakse nimi b.
- Määrake muutuja a aadressi b väärtused.
- Käivitage tuletatud klassis defineeritud funktsioon show(). Hiline sidumine on rakendatud.
- Funktsiooni main() keha lõpp.
Kompileerimise aja polümorfism vs. Käitusaja polümorfism
Siin on peamised erinevused nende kahe vahel.
| Kompileerimisaegne polümorfism | Run-time polümorfism |
|---|---|
| Seda nimetatakse ka varaseks sidumiseks või staatiliseks polümorfismiks | Seda nimetatakse ka hiliseks/dünaamiliseks sidumiseks või dünaamiliseks polümorfismiks |
| Meetodit kutsutakse/kutsutakse välja kompileerimise ajal | Meetodit kutsutakse/kutsutakse välja käitamise ajal |
| Rakendatakse funktsioonide ülekoormuse ja operaatori ülekoormuse kaudu | Rakendatakse meetodi alistamise ja virtuaalsete funktsioonide kaudu |
| Näide, meetodi ülekoormus. Paljudel meetoditel võivad olla sarnased nimed, kuid erinev arv või argumentide tüüp | Näide, meetodi ületamine. Paljudel meetoditel võib olla sarnane nimi ja sama prototüüp. |
| Kiirem täitmine, kuna meetodite avastamine toimub kompileerimise ajal | Aeglasem täitmine, kuna meetodi avastaja tehakse käitusajal. |
| Less Paindlikkus probleemide lahendamiseks on tagatud, kuna kompileerimise ajal on kõik teada. | Keeruliste probleemide lahendamiseks pakutakse palju paindlikkust, kuna meetodid avastatakse käitusajal. |
kokkuvõte
- Polümorfism tähendab paljude vormide olemasolu.
- See tekib siis, kui on olemas pärimise kaudu seotud klasside hierarhia.
- Polümorfismi korral võib funktsioon käituda erinevalt olenevalt objektist, mis seda kutsub/kutsub.
- Kompileerimisaja polümorfismi korral määratakse käivitatav funktsioon kompileerimise ajal.
- Käitusaja polümorfismi korral määratakse käivitatav funktsioon käitusaja jooksul.
- Kompileerimisaja polümorfism määratakse funktsioonide ülekoormuse ja operaatori ülekoormuse kaudu.
- Funktsioonide ülekoormuse korral on palju sarnase nimega, kuid erinevate argumentidega funktsioone.
- Parameetrid võivad arvu või tüübi poolest erineda.
- Operaatori ülekoormuse korral määratletakse uus tähendus C++ ettevõtjad.
- Käitusaegne polümorfism saavutatakse funktsiooni alistamise kaudu.
- Funktsiooni alistamise korral annab tuletatud klass baasklassis defineeritud funktsioonile uue definitsiooni.







