Esittely latautuu. Ole hyvä ja odota

Esittely latautuu. Ole hyvä ja odota

Virtuaaliset jäsenfunktiot tMyn1 Virtuaaliset jäsenfunktiot Virtuaalinen jäsenfunktio on esiteltävä monimuotoisessa kantaluokassa. Virtuaalisen jäsenfunktion.

Samankaltaiset esitykset


Esitys aiheesta: "Virtuaaliset jäsenfunktiot tMyn1 Virtuaaliset jäsenfunktiot Virtuaalinen jäsenfunktio on esiteltävä monimuotoisessa kantaluokassa. Virtuaalisen jäsenfunktion."— Esityksen transkriptio:

1 Virtuaaliset jäsenfunktiot tMyn1 Virtuaaliset jäsenfunktiot Virtuaalinen jäsenfunktio on esiteltävä monimuotoisessa kantaluokassa. Virtuaalisen jäsenfunktion oletustoteutus kirjoitetaan monimuotoiseen kantaluokkaan ja oletustoteutuksen korvaavat toteutusratkaisut kirjoitetaan tarvittaessa monimuotoisesta kantaluokasta johdettuihin luokkiin.

2 Virtuaaliset jäsenfunktiot tMyn2 Virtuaalisen jäsenfunktion esittely: class kantaLuokka { public: virtual jasenFunktio(); … };

3 Virtuaaliset jäsenfunktiot tMyn3 Varattu sana virtual kertoo, että luokka sisältää jäsenfunktion oletustoteutuksen. Johdetuissa luokissa voi olla useita oletustoteutuksen korvaavia toteutuksia. Johdettuun luokkaan toteutettavan (override) jäsenfunktion esittelyn on vastattava monimuotoisessa kantaluokassa esiteltyä virtuaalista jäsenfunktiota. Siis: –nimen on oltava sama kuin kantaluokassakin. –parametrien lukumäärän ja tyyppien on oltava samat kuin kantaluokassa – ja samassa järjestyksessä. –jäsenfunktion tyypin on oltava sama kuin kantaluokassa.

4 Virtuaaliset jäsenfunktiot tMyn4 Oletustoteutuksen korvaaminen johdetussa luokassa: class johdettuLuokka:public kantaLuokka { public: virtual jasenFunktio(); … }; //jasenFunktion toteutus

5 Virtuaaliset jäsenfunktiot tMyn5 Varattu sana virtual siis lisätään jäsenfunktion eteen luokan toteutuksen yhteydessä. Kun jäsenfunktion runko toteutetaan, niin silloin ei enää lisätä sanaa virtual. Kun kantaluokassa jokin jäsenfunktio määritellään virtual-tyyppiseksi, niin vastaavasti kaikki johdetuissa luokissa korvatut (redefine->override) funktiot muuttuvat virtual-tyyppisiksi. Symmetriasyistä (ja selvyyden vuoksi) tällainen johdetun luokan jäsenfunktio voidaan/kannattanee merkitä virtual- tyyppiseksi kyseisen luokan määrittelyssä.

6 Virtuaaliset jäsenfunktiot tMyn6 Virtuaalista jäsenfunktiota käytetään viittaamalla epäsuorasti määriteltyyn olioon. Epäsuoralla viittauksella tarkoitetaan tunnusta, joka on osoitin tai viittaus olioon. Dynaamista sidontaa ei siis tapahdu käytettäessä automaattista tunnusta. Dynaaminen sidonta toteutetaan kantaluokan osoitinta käyttäen: kantaLuokka* tunnus=&automaattinenOlio; tunnus->jasenFunktio();

7 Virtuaaliset jäsenfunktiot tMyn7 kantaLuokka* tunnus=dynaaminenOlio; tunnus->jasenFunktio(); Olio voi olla automaattinen tai dynaaminen. Otetaan esimerkkinä äskeinen ohjelma. Tarvittava muutos on pieni!! Huom! Tehdään vielä se muutos tuohon edelliseen esimerkkiin (joka oli käytössä luvussa Monimuotoinen luokka), että muutetaan tietojäsenet dynaamisiksi, jotta nähdään hajotinten toimivuus (tai toimimattomuus). Aluksi operoidaan automaattisen olion kanssa:

8 Virtuaaliset jäsenfunktiot tMyn8 // Laatikko.h #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko { public: Laatikko(); void AsetaLeveys(); void AsetaSyvyys(); void AsetaKorkeus(); Laatikko(double, double, double); void AsetaLeveys(double); void AsetaSyvyys(double); void AsetaKorkeus(double); ~Laatikko(); void HaeTilavuus(); virtual double LaskeTilavuus();

9 Virtuaaliset jäsenfunktiot tMyn9 protected: double* mp_leveys; double* mp_syvyys; double* mp_korkeus; }; #endif

10 Virtuaaliset jäsenfunktiot tMyn10 // Pahvilaatikko.h #ifndef PAHVILAATIKKO_H #define PAHVILAATIKKO_H #include "Laatikko.h" class Pahvilaatikko: public Laatikko { public: Pahvilaatikko(); void AsetaPaino(); Pahvilaatikko(double); void AsetaPaino(double); Pahvilaatikko(double, double, double, double); ~Pahvilaatikko(); virtual double LaskeTilavuus(); private: double* mp_paino; }; #endif

11 Virtuaaliset jäsenfunktiot tMyn11 // Laatikko.cpp #include "stdafx.h" #include #include "Laatikko.h" using namespace System; using namespace std; Laatikko::Laatikko() { cout<<"Kantaluokan oletusmuodostin, olio "<<this<<endl; mp_leveys=new double; AsetaLeveys(); mp_syvyys=new double; AsetaSyvyys(); mp_korkeus=new double; AsetaKorkeus(); }

12 Virtuaaliset jäsenfunktiot tMyn12 void Laatikko::AsetaLeveys() { cout<<"Anna leveys: "; cin>>*mp_leveys; cin.get(); } void Laatikko::AsetaSyvyys() { cout<<"Anna syvyys: "; cin>>*mp_syvyys; cin.get(); } void Laatikko::AsetaKorkeus() { cout<<"Anna korkeus: "; cin>>*mp_korkeus; cin.get(); }

13 Virtuaaliset jäsenfunktiot tMyn13 Laatikko::Laatikko(double leveys, double syvyys, double korkeus) { cout<<"Kantaluokan 3 param. muodostin, olio "<<this<<endl; mp_leveys=new double; AsetaLeveys(leveys); mp_syvyys=new double; AsetaSyvyys(syvyys); mp_korkeus=new double; AsetaKorkeus(korkeus); } void Laatikko::AsetaLeveys(double leveys) { *mp_leveys=leveys; } void Laatikko::AsetaSyvyys(double syvyys) { *mp_syvyys=syvyys; }

14 Virtuaaliset jäsenfunktiot tMyn14 void Laatikko::AsetaKorkeus(double korkeus) { *mp_korkeus=korkeus; } Laatikko::~Laatikko() { cout<<"Kantaluokan hajotin, olio "<<this<<endl; delete mp_leveys; delete mp_syvyys; delete mp_korkeus; } void Laatikko::HaeTilavuus() { cout<<"Tilavuus, olio "<<this<<" on "<<LaskeTilavuus()<<endl; } double Laatikko::LaskeTilavuus() { return *mp_leveys*(*mp_syvyys)*(*mp_korkeus); }

15 Virtuaaliset jäsenfunktiot tMyn15 // Pahvilaatikko.cpp #include "stdafx.h" #include #include "Pahvilaatikko.h" using namespace System; using namespace std; Pahvilaatikko::Pahvilaatikko() :Laatikko() { cout<<"Johdetun luokan oletusmuodostin, olio "<<this<<endl; mp_paino=new double; AsetaPaino(); }

16 Virtuaaliset jäsenfunktiot tMyn16 void Pahvilaatikko::AsetaPaino() { cout<<"Anna paino: "; cin>>*mp_paino; cin.get(); } Pahvilaatikko::Pahvilaatikko(double paino) :Laatikko() { cout<<"Johdetun luokan 1 param. muodostin, olio "<<this<<endl; mp_paino=new double; AsetaPaino(paino); } void Pahvilaatikko::AsetaPaino(double paino) { *mp_paino=paino; }

17 Virtuaaliset jäsenfunktiot tMyn17 Pahvilaatikko::Pahvilaatikko(double leveys, double syvyys, double korkeus, double paino) :Laatikko(leveys, syvyys, korkeus) { cout<<"Johdetun luokan 4 param. muodostin, olio "<<this<<endl; mp_paino=new double; AsetaPaino(paino); } Pahvilaatikko::~Pahvilaatikko() { cout<<"Johdetun luokan hajotin, olio "<<this<<endl; delete mp_paino; } double Pahvilaatikko::LaskeTilavuus() { return 0.85*(*mp_leveys)*(*mp_syvyys)*(*mp_korkeus); }

18 Virtuaaliset jäsenfunktiot tMyn18 // moni1Main.cpp : main project file. #include "stdafx.h" #include #include "Pahvilaatikko.h" using namespace System; using namespace std; int main(array ^args) { Laatikko eka=Laatikko(1.1, 2.2, 3.3); Pahvilaatikko toka=Pahvilaatikko(1.1, 2.2, 3.3, 68.9); Laatikko* osoitin=&eka; osoitin->HaeTilavuus(); osoitin=&toka; osoitin->HaeTilavuus(); return 0; }

19 Virtuaaliset jäsenfunktiot tMyn19

20 Virtuaaliset jäsenfunktiot tMyn20 Seuraavaksi muuten sama, mutta kokeillaan dynaamisilla olioilla:

21 Virtuaaliset jäsenfunktiot tMyn21 //Sama kuin edellisessä esimerkissä … // moni2Main.cpp : main project file. #include "stdafx.h" #include #include "Pahvilaatikko.h" using namespace System; using namespace std; int main(array ^args) { Laatikko* eka=new Laatikko(1.1, 2.2, 3.3); Pahvilaatikko* toka=new Pahvilaatikko(1.1, 2.2, 3.3, 68.9); Laatikko* osoitin=eka; osoitin->HaeTilavuus(); osoitin=toka; osoitin->HaeTilavuus();

22 Virtuaaliset jäsenfunktiot tMyn22 Laatikko* kolmas=new Pahvilaatikko(1.1, 2.2, 3.3, 79.8); osoitin=kolmas; osoitin->HaeTilavuus(); delete eka; delete toka; delete kolmas; return 0; }

23 Virtuaaliset jäsenfunktiot tMyn23

24 Virtuaaliset jäsenfunktiot tMyn24 Edellisestä diasta huomataan, että ihan kaikki ei ole vielä kunnossa! Jos kantaluokan hajotin ei ole virtuaalinen ja ohjelma käsittelee johdetun luokan olioita monimuotoisen kantaluokan tyyppisellä osoittimella (olio kolmas), järjestelmä kutsuu olion tunnuksen tilanvapautuksen yhteydessä ainoastaan kantaluokan hajotinta. Olion määrittelyluokan hajotin (johdetun luokan hajotin) jää kutsumatta ja mahdolliset dynaamiset tietojäsenet jäävät niin muodoin vapauttamatta. Tehdään siis edelliseen yksi muutos: esitellään kantaluokan hajotin varatulla sanalla virtual.

25 Virtuaaliset jäsenfunktiot tMyn25 Nyt kun kantaluokassa on virtuaalinen hajotin, niin johdetun luokan hajotin muuttuu myös virtuaaliseksi. Johdetun luokan määrittelyyn voidaan myös lisätä tuo varattu sama virtual hajottimen eteen. Kullakin luokalla on luokkansa niminen hajotin. Tämä virtuaalinen hajotin on siis jonkin tyyppinen erikoistapaus C++:ssa.

26 Virtuaaliset jäsenfunktiot tMyn26 // Laatikko.h #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko { public: Laatikko(); void AsetaLeveys(); void AsetaSyvyys(); void AsetaKorkeus(); Laatikko(double, double, double); void AsetaLeveys(double); void AsetaSyvyys(double); void AsetaKorkeus(double); virtual ~Laatikko(); void HaeTilavuus(); virtual double LaskeTilavuus();

27 Virtuaaliset jäsenfunktiot tMyn27 protected: double* mp_leveys; double* mp_syvyys; double* mp_korkeus; }; #endif

28 Virtuaaliset jäsenfunktiot tMyn28 // Pahvilaatikko.h #ifndef PAHVILAATIKKO_H #define PAHVILAATIKKO_H #include "Laatikko.h" class Pahvilaatikko: public Laatikko { public: Pahvilaatikko(); void AsetaPaino(); Pahvilaatikko(double); void AsetaPaino(double); Pahvilaatikko(double, double, double, double); virtual ~Pahvilaatikko(); virtual double LaskeTilavuus(); private: double* mp_paino; }; #endif

29 Virtuaaliset jäsenfunktiot tMyn29 // Laatikko.cpp #include "stdafx.h" #include #include "Laatikko.h" using namespace System; using namespace std; Laatikko::Laatikko() { cout<<"Kantaluokan oletusmuodostin, olio "<<this<<endl; mp_leveys=new double; AsetaLeveys(); mp_syvyys=new double; AsetaSyvyys(); mp_korkeus=new double; AsetaKorkeus(); }

30 Virtuaaliset jäsenfunktiot tMyn30 void Laatikko::AsetaLeveys() { cout<<"Anna leveys: "; cin>>*mp_leveys; cin.get(); } void Laatikko::AsetaSyvyys() { cout<<"Anna syvyys: "; cin>>*mp_syvyys; cin.get(); } void Laatikko::AsetaKorkeus() { cout<<"Anna korkeus: "; cin>>*mp_korkeus; cin.get(); }

31 Virtuaaliset jäsenfunktiot tMyn31 Laatikko::Laatikko(double leveys, double syvyys, double korkeus) { cout<<"Kantaluokan 3 param. muodostin, olio "<<this<<endl; mp_leveys=new double; AsetaLeveys(leveys); mp_syvyys=new double; AsetaSyvyys(syvyys); mp_korkeus=new double; AsetaKorkeus(korkeus); } void Laatikko::AsetaLeveys(double leveys) { *mp_leveys=leveys; } void Laatikko::AsetaSyvyys(double syvyys) { *mp_syvyys=syvyys; }

32 Virtuaaliset jäsenfunktiot tMyn32 void Laatikko::AsetaKorkeus(double korkeus) { *mp_korkeus=korkeus; } Laatikko::~Laatikko() { cout<<"Kantaluokan hajotin, olio "<<this<<endl; delete mp_leveys; delete mp_syvyys; delete mp_korkeus; } void Laatikko::HaeTilavuus() { cout<<"Tilavuus, olio "<<this<<" on "<<LaskeTilavuus()<<endl; } double Laatikko::LaskeTilavuus() { return *mp_leveys*(*mp_syvyys)*(*mp_korkeus); }

33 Virtuaaliset jäsenfunktiot tMyn33 // Pahvilaatikko.cpp #include "stdafx.h" #include #include "Pahvilaatikko.h" using namespace System; using namespace std; Pahvilaatikko::Pahvilaatikko() :Laatikko() { cout<<"Johdetun luokan oletusmuodostin, olio "<<this<<endl; mp_paino=new double; AsetaPaino(); }

34 Virtuaaliset jäsenfunktiot tMyn34 void Pahvilaatikko::AsetaPaino() { cout<<"Anna paino: "; cin>>*mp_paino; cin.get(); } Pahvilaatikko::Pahvilaatikko(double paino) :Laatikko() { cout<<"Johdetun luokan 1 param. muodostin, olio "<<this<<endl; mp_paino=new double; AsetaPaino(paino); } void Pahvilaatikko::AsetaPaino(double paino) { *mp_paino=paino; }

35 Virtuaaliset jäsenfunktiot tMyn35 Pahvilaatikko::Pahvilaatikko(double leveys, double syvyys, double korkeus, double paino) :Laatikko(leveys, syvyys, korkeus) { cout<<"Johdetun luokan 4 param. muodostin, olio "<<this<<endl; mp_paino=new double; AsetaPaino(paino); } Pahvilaatikko::~Pahvilaatikko() { cout<<"Johdetun luokan hajotin, olio "<<this<<endl; delete mp_paino; } double Pahvilaatikko::LaskeTilavuus() { return 0.85*(*mp_leveys)*(*mp_syvyys)*(*mp_korkeus); }

36 Virtuaaliset jäsenfunktiot tMyn36 // moni2aMain.cpp : main project file. #include "stdafx.h" #include #include "Pahvilaatikko.h" using namespace System; using namespace std; int main(array ^args) { Laatikko* eka=new Laatikko(1.1, 2.2, 3.3); Pahvilaatikko* toka=new Pahvilaatikko(1.1, 2.2, 3.3, 68.9); Laatikko* osoitin=eka; osoitin->HaeTilavuus(); osoitin=toka; osoitin->HaeTilavuus();

37 Virtuaaliset jäsenfunktiot tMyn37 Laatikko* kolmas=new Pahvilaatikko(1.1, 2.2, 3.3, 79.8); osoitin=kolmas; osoitin->HaeTilavuus(); delete eka; delete toka; delete kolmas; return 0; }

38 Virtuaaliset jäsenfunktiot tMyn38

39 Virtuaaliset jäsenfunktiot tMyn39 Yhteenveto dynaamisesta sidonnasta Late binding, dynamic binding. Olion käyttäytymistavan määrää olion määrittelyluokkaan toteutettu jäsenfunktio. Monella tapaa toteutettavissa olevaa jäsenfunktiota kutsutaan virtuaaliseksi jäsenfunktioksi. Virtuaalinen jäsenfunktio on funktio, josta löytyy useita toteutusratkaisuja ja jonka kutsua vastaavan toteutustavan järjestelmä etsii olion määrittelyluokasta ohjelman suorituksen aikana.

40 Virtuaaliset jäsenfunktiot tMyn40 Kääntäjä ei voi etukäteen (=staattisesti, käännösvaiheessa) päätellä olion määrittelyluokkaa, koska ohjelmassa esitelty oliotunnus (osoitinmuuttuja tai viittaus) voi viitata eri aikoina ohjelmaa eri olioihin. Oliot voivat olla eri luokista. Virtuaalista jäsenfunktiota tulee käyttää ainoastaan viittaamalla epäsuorasti määriteltyyn olioon (siis käyttää niin, että sidonta tapahtuu ajonaikaisesti). Epäsuoralla viittauksella tarkoitetaan oliotunnusta, joka on osoitin tai viittaus olioon. Itse olio voi olla automaattinen tai dynaaminen.

41 Virtuaaliset jäsenfunktiot tMyn41 Polymorfismi on prosessi, jonka avulla saavutetaan yhteinen liittymä kahdelle tai useammalle samankaltaiselle (teknisesti erilaiselle) toiminnolle. Siis toteutetaan yksi liittymä, monta metodia filosofia. Polymorfismin avulla voidaan huomattavasti yksinkertaistaa monimutkaisia järjestelmiä. Käytetään yhtä hyvin määriteltyä liittymää ja suoritetaan erilaisia mutta yhteenkuuluvia toiminteita, jolloin keinotekoinen kompleksisuus katoaa.

42 Virtuaaliset jäsenfunktiot tMyn42 Syötetään lasta, syötetään jääkiekossa, syötetään jalkapallossa, syötetään paperia kirjoittimeen, jne: kaikki ovat syöttämisiä, mutta tapauskohtaisesti toiminta voi olla hyvinkin erilaista. Polymorfismin avulla ohjelmat tulevat helpommin ymmärrettäviksi ja ylläpidettäviksi. Tarvitsee muistaa vähemmän, kun samankaltaisilla toimenpiteillä on samanlainen liittymä.

43 Virtuaaliset jäsenfunktiot tMyn43 Kun virtuaalifunktiota kutsutaan kantaluokan osoittimen avulla, ohjelman on pääteltävä ajon aikana, minkä tyyppistä oliota kantaluokan osoitin osoittaa ja sitten valittava kyseiseen tyyppiin liittyvä virtuaalifunktion versio. Päähyöty myöhaisestä sidonnasta on ajonaikaisessa joustavuudessa. Ohjelma voi käsitellä suurta joukkoa satunnaisia tapahtumia ilman valtavaa ehtojen käsittelykoodia (if... elseif... elseif...). Päähaitta on funktiokutsuihin liittyvässä järjestelmän tuottamassa lisäkuormassa. Tällaiset funktiokutsut ovat yleensä hitaampia kuin aikaisen sidonnan kutsut.

44 Virtuaaliset jäsenfunktiot tMyn44 Käyttöjärjestelmissä kuten Windows järjestelmän liittymä ohjelmiin tapahtuu sanomien välityksellä. Näitä sanomia generoituu satunnaisesti riippuen käyttäjän ja järjestelmän toiminnasta. Ohjelman on vastattava saamiinsa sanomiin. Kuten arvata saattaa ajonaikaisesta polymorfismista on hyötyä ohjelmissa, jotka on tehty tämän tyyppisiin järjestelmiin.


Lataa ppt "Virtuaaliset jäsenfunktiot tMyn1 Virtuaaliset jäsenfunktiot Virtuaalinen jäsenfunktio on esiteltävä monimuotoisessa kantaluokassa. Virtuaalisen jäsenfunktion."

Samankaltaiset esitykset


Iklan oleh Google