Esittely latautuu. Ole hyvä ja odota

Esittely latautuu. Ole hyvä ja odota

Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan.

Samankaltaiset esitykset


Esitys aiheesta: "Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan."— Esityksen transkriptio:

1 Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan olemassa olevan olion tiedoilla. Kääntäjä generoi kopiointimuodostimen, joka kopioi uudelle oliolle parametrina välitetyn saman luokan olion tietojäsenten sisällön. Ohjelmoija voi määritellä kopiointimuodostimen myös itse, jos kääntäjän generoiman muodostimen toiminta ei tyydytä.

2 Olioon kohdistuvia perustoimintoja tMyn2 Automaattisen olion tilanvaraus ja kopiointimuodostimen kutsu: Luokka uusiAutomOlio(vanhaAutomOlio); Luokka uusiAutomOlio=vanhaAutomOlio; Luokka uusiAutomOlio(*vanhaDynOlio); Luokka uusiAutomOlio=*vanhaDynOlio;

3 Olioon kohdistuvia perustoimintoja tMyn3 Dynaamisen olion tilanvaraus ja kopiointimuodostimen kutsu: Luokka *uusiDynOlio; uusiDynOlio=new Luokka(vanhaAutomOlio); uusiDynOlio=new Luokka(*vanhaDynOlio); Koska seuraavana kappaleena on ”Dynaamiset oliot”, niin käsitellään tässä yhteydessä automaattisen olion tietojäseniä – sekä automaattisia että dynaamisia tietojäseniä.

4 Olioon kohdistuvia perustoimintoja tMyn4 Ohjelmoija voi myös itse määritellä kopiointimuodostimen. Silloin tulee muistaa: –Kopiointimuodostimen ensimmäinen parametri on viittaus saman luokan olioon. –Viittaus voi olla määritelty vakioksi const-määreellä. –Kopiointimuodostimen muilla mahdollisilla parametreilla tulee olla oletusarvo. –Jos ohjelmoija määrittelee kopiointimuodostimen, ei kääntäjä generoi oletusmuodostinta.

5 Olioon kohdistuvia perustoimintoja tMyn5 Kopiointimuodostimen esittelytavat: Luokka (const Luokka&); Luokka (const Luokka&, parametri=alkuarvo,...); Seuraavassa esimerkissä itse tehdyssä kopiointimuodostimessa korkeudelle on annettu oletusarvo – siis kun luodaan uusi olio tällaisella kopiointimuodostimella, niin syntynyt olio ei ole identtinen mallinsa kanssa.

6 Olioon kohdistuvia perustoimintoja tMyn6 #include "stdafx.h" #include using namespace System; using namespace std; class Laatikko { public: Laatikko(double, double, double); Laatikko(const Laatikko&, double=6.8); void AsetaLeveys(double); void AsetaSyvyys(double); void AsetaKorkeus(double); double LaskeTilavuus(); private: double m_leveys; double m_syvyys; double m_korkeus; };

7 Olioon kohdistuvia perustoimintoja tMyn7 Laatikko::Laatikko(double leveys, double syvyys, double korkeus) { cout<<"Param. muodostin, olio "<<this<<endl; AsetaLeveys(leveys); AsetaSyvyys(syvyys); AsetaKorkeus(korkeus); } void Laatikko::AsetaLeveys(double leveys) { m_leveys=leveys; } void Laatikko::AsetaSyvyys(double syvyys) { m_syvyys=syvyys; } void Laatikko::AsetaKorkeus(double korkeus) { m_korkeus=korkeus; }

8 Olioon kohdistuvia perustoimintoja tMyn8 Laatikko::Laatikko(const Laatikko& viittaus, double korkeus) { cout<<"Kopiointimuodostin, olio "<<this<<endl; m_leveys=viittaus.m_leveys; m_syvyys=viittaus.m_syvyys; m_korkeus=korkeus; } double Laatikko::LaskeTilavuus() { return m_leveys*m_syvyys*m_korkeus; }

9 Olioon kohdistuvia perustoimintoja tMyn9 int main(array ^args) { Laatikko ekaAito(2.1, 3.2, 4.3); Laatikko ekaKopio=ekaAito; Laatikko tokaKopio(ekaAito, 5.7); cout<<"Tilavuus, ekaAito: " <<ekaAito.LaskeTilavuus()<<"."<<endl; cout<<"Tilavuus, ekaKopio: " <<ekaKopio.LaskeTilavuus()<<"."<<endl; cout<<"Tilavuus, tokaKopio: " <<tokaKopio.LaskeTilavuus()<<"."<<endl; ekaAito.AsetaLeveys(2.11); cout<<"Tilavuus lopuksi, ekaAito: " <<ekaAito.LaskeTilavuus()<<"."<<endl; return 0; }

10 Olioon kohdistuvia perustoimintoja tMyn10

11 Olioon kohdistuvia perustoimintoja tMyn11 Olion tilanvarauksen jälkeen olemassa olevan olion tietojäsenet voidaan muuttaa sijoitusoperaattorilla (=) samoiksi kuin mitä jonkin saman luokan olion tietojäsenet ovat. Kopioinnissa on aina kysymys uuden olion luonnista kopiointimuodostimen avulla, kun taas sijoituksessa jo olemassa olevan olion tietojäsenten arvot korvautuvat uusilla. Sijoitus olemassa olevaan saman luokan olioon: olenOlemassa=niinMinakin; Käytetään edellistä esimerkkiohjelmaa:

12 Olioon kohdistuvia perustoimintoja tMyn12 //sama kuin edellinen esimerkki … int main(array ^args) { Laatikko ekaAito(2.1, 3.2, 4.3); Laatikko ekaKopio=ekaAito; Laatikko tokaKopio(ekaAito, 5.7); cout<<"Tilavuus, ekaAito: " <<ekaAito.LaskeTilavuus()<<"."<<endl; cout<<"Tilavuus, ekaKopio: " <<ekaKopio.LaskeTilavuus()<<"."<<endl; cout<<"Tilavuus, tokaKopio: " <<tokaKopio.LaskeTilavuus()<<"."<<endl; ekaAito.AsetaLeveys(2.11); cout<<"Tilavuus nyt, ekaAito: " <<ekaAito.LaskeTilavuus()<<"."<<endl; ekaAito=ekaKopio; cout<<"Tilavuus lopuksi, ekaAito: " <<ekaAito.LaskeTilavuus()<<"."<<endl; return 0; }

13 Olioon kohdistuvia perustoimintoja tMyn13

14 Olioon kohdistuvia perustoimintoja tMyn14 Hajotin (destructor) on luokan jäsenfunktio, jonka toiminta on käänteinen muodostimen toimintaan nähden. Hajottimen tarkoituksena on tyhjentää olion tietojäsenet ja vapauttaa olion sisäiset rakenteet. Järjestelmä kutsuu hajotinta olion tilanvapautuksen yhteydessä automaattisesti. Hajotinta voidaan kutsua ohjelmallisesti myös ennen olion tilanvapautusta, kun olio halutaan väliaikaisesti tyhjentää. Tämä on harvinaista. Kääntäjä generoi luokalle hajottimen, jos ohjelmoija ei sitä itse kirjoita.

15 Olioon kohdistuvia perustoimintoja tMyn15 Hajottimella on erityistä merkitystä, jos luokassa on esitelty dynaamisia tietojäseniä. Jos hajotin rakennetaan itse, niin on syytä muistaa: –hajottimen nimi on luokan nimi ja sen edessä on merkki ~ –hajotin ei saa parametrejä –hajottimella ei ole tyyppiä Hajottimen kutsu tapahtuu automaattisesti olion tilanvapautuksen yhteydessä. Automaattisen olion tila vapautuu olion luoneen lohkon lopussa. Dynaamisten olioiden yhteydessä delete-operaattorin käyttö aiheuttaa hajottimen kutsun.

16 Olioon kohdistuvia perustoimintoja tMyn16 Hajottimen toteutus: Luokka::~Luokka() { dynaamisten tietojäsenten varaaman tilan vapauttaminen } Jos oliolla on dynaamisia tietojäseniä, niin ohjelmoijan on toteutettava luokkaan oma hajotin, joka vapauttaa dynaamisesti varatun tilan.

17 Olioon kohdistuvia perustoimintoja tMyn17 #include "stdafx.h" #include using namespace System; using namespace std; class Ympyra { public: Ympyra(); void AsetaSade(); void AsetaViivanPaksuus(); Ympyra(double, double); void AsetaSade(double); void AsetaViivanPaksuus(double); ~Ympyra(); double LaskeAla(); private: double m_sade; double* mp_viivanpaksuus; };

18 Olioon kohdistuvia perustoimintoja tMyn18 Ympyra::Ympyra() { cout<<"Oletusmuodostin, olio "<<this<<"."<<endl; AsetaSade(); mp_viivanpaksuus=new double; AsetaViivanPaksuus(); } void Ympyra::AsetaSade() { cout<<"Anna s\204de: "; cin>>m_sade; } void Ympyra::AsetaViivanPaksuus() { cout<<"Anna viivan paksuus: "; cin>>*mp_viivanpaksuus; }

19 Olioon kohdistuvia perustoimintoja tMyn19 Ympyra::Ympyra(double sade, double viivanpaksuus) { cout<<"Parametrillinen muodostin, luodaan olio " <<this<<"."<<endl; AsetaSade(sade); mp_viivanpaksuus=new double; AsetaViivanPaksuus(viivanpaksuus); } void Ympyra::AsetaSade(double sade) { m_sade=sade; } void Ympyra::AsetaViivanPaksuus(double viivanpaksuus) { *mp_viivanpaksuus=viivanpaksuus; }

20 Olioon kohdistuvia perustoimintoja tMyn20 Ympyra::~Ympyra() { cout<<"Hajotin, olio "<<this<<"."<<endl; delete mp_viivanpaksuus; mp_viivanpaksuus=0; } double Ympyra::LaskeAla() { const double pii=3.141593; return pii*m_sade*m_sade; }

21 Olioon kohdistuvia perustoimintoja tMyn21 int main(array ^args) { Ympyra eka=Ympyra(); cout<<"Ala eka alussa: "<<eka.LaskeAla()<<endl; Ympyra toka=Ympyra(4.567, 0.1345); cout<<"Ala, toka: "<<toka.LaskeAla()<<endl; eka.AsetaSade(); cout<<"Ala eka keskell\204: "<<eka.LaskeAla()<<endl; eka.AsetaSade(12.945); cout<<"Ala eka lopuksi: "<<eka.LaskeAla()<<endl; return 0; }

22 Olioon kohdistuvia perustoimintoja tMyn22

23 Olioon kohdistuvia perustoimintoja tMyn23 Nyt kun hajotin on esitelty, voidaan palata kopiointimuodostimen toimintaan. Sellaisessa tapauksessa, että oliolla on dynaamisesti allokoituja tietojäseniä, järjestelmän generoima kopiointimuodostin ei toimi halutulla tavalla. Testataan aluksi, että näin tosiaan on antamalla järjestelmän generoida oletusmuotoisen kopiointimuodostimen:

24 Olioon kohdistuvia perustoimintoja tMyn24 #include "stdafx.h" #include using namespace System; using namespace std; class A { public: A(); A(int); void AsetaArvo(); void AsetaArvo(int); void HaeArvo(); private: int* mp_arvo; };

25 Olioon kohdistuvia perustoimintoja tMyn25 A::A() { cout<<"Oletusmuodostin, olio "<<this<<endl; mp_arvo=new int; AsetaArvo(); } A::A(int arvo) { cout<<"Parametrillinen muodostin, olio "<<this<<endl; mp_arvo=new int; AsetaArvo(arvo); } void A::AsetaArvo() { cout<<"Anna arvo: "; cin>>*mp_arvo; }

26 Olioon kohdistuvia perustoimintoja tMyn26 void A::HaeArvo() { cout<<"Tietoj\204senen arvo on "<<*mp_arvo<<", olio ” <<this<<endl; };

27 Olioon kohdistuvia perustoimintoja tMyn27 int main(array ^args) { A ekaAutoAlkup=A(); cout<<"Alkuper\204isen olion tietoj\204senen arvo alussa:” <<endl; ekaAutoAlkup.HaeArvo(); cout<<"J\204rjestelm\204n generoima kopiointimuodostin:” <<endl; A ekaAutoKopio=ekaAutoAlkup; ekaAutoKopio.HaeArvo(); cout<<"Yritet\204\204n tehd\204 muutos vain kopioidun \ olion tietoj\204senelle:”<<endl; ekaAutoKopio.AsetaArvo(1957); cout<<"Kopioidun olion tietoj\204sen:"<<endl; ekaAutoKopio.HaeArvo(); cout<<"Alkuper\204isen olion tietoj\204senen arvo lopuksi:” <<endl; ekaAutoAlkup.HaeArvo(); return 0; }

28 Olioon kohdistuvia perustoimintoja tMyn28

29 Olioon kohdistuvia perustoimintoja tMyn29 Ongelmana on siis se, että kopioitavan olion osoitintietojäsenet kopioituvat uuteen olioon osoitteina. Eli kahdessa oliossa on osoitin samaan muistiosoitteeseen. Jos toinen olioista tuhotaan niin myös osoitettavan muistipaikan sisältö tuhotaan. Oletuskopiointimuodostin ei siis toimi tällaisessa tapauksessa! Jos nyt äskeiseen ohjelmaan lisättäisiin hajotin, niin yllämainitusta syystä muutos aiheuttaisi virhetilanteen. Pidetään ohjelma muuten samana:

30 Olioon kohdistuvia perustoimintoja tMyn30 //sama kuin edellinen esimerkki class A { public: A(); A(int); ~A(); void AsetaArvo(); void AsetaArvo(int); void HaeArvo(); private: int* mp_arvo; }; //sama kuin edellinen esimerkki … A::~A() { cout<<"Hajotin, olio "<<this<<endl; delete mp_arvo; } …

31 Olioon kohdistuvia perustoimintoja tMyn31 Kun ohjelmaa yrittää nyt ajaa hajottimen lisäyksen jälkeen…:

32 Olioon kohdistuvia perustoimintoja tMyn32 Tehdään edelliseen ohjelmaan oma kopiointimuodostin, jolloin edellä kuvattuja ongelmia ei enää synny:

33 Olioon kohdistuvia perustoimintoja tMyn33 #include "stdafx.h" #include using namespace System; using namespace std; class A { public: A(); A(int); A(const A&); ~A(); void AsetaArvo(); void AsetaArvo(int); void HaeArvo(); private: int* mp_arvo; };

34 Olioon kohdistuvia perustoimintoja tMyn34 A::A() { cout<<"Oletusmuodostin, olio "<<this<<endl; mp_arvo=new int; AsetaArvo(); } A::A(int arvo) { cout<<"Parametrillinen muodostin, olio "<<this<<endl; mp_arvo=new int; AsetaArvo(arvo); } A::A(const A& viittaus) { cout<<"Kopiointimuodostin, olio "<<this<<endl; mp_arvo=new int; *mp_arvo=*(viittaus.mp_arvo); }

35 Olioon kohdistuvia perustoimintoja tMyn35 A::~A() { cout<<"Hajotin, olio "<<this<<endl; delete mp_arvo; } void A::AsetaArvo() { cout<<"Anna arvo: "; cin>>*mp_arvo; } void A::AsetaArvo(int arvo) { *mp_arvo=arvo; } void A::HaeArvo() { cout<<"Tietoj\204senen arvo on "<<*mp_arvo<<", olio ” <<this<<endl; };

36 Olioon kohdistuvia perustoimintoja tMyn36 int main(array ^args) { A ekaAutoAlkup=A(); cout<<"Alkuper\204isen olion tietoj\204senen arvo alussa:"<<endl; ekaAutoAlkup.HaeArvo(); cout<<"J\204rjestelm\204n generoima kopiointimuodostin:"<<endl; A ekaAutoKopio=ekaAutoAlkup; ekaAutoKopio.HaeArvo(); cout<<"Yritet\204\204n tehd\204 muutos vain \ kopioidun olion tietoj\204senelle:"<<endl; ekaAutoKopio.AsetaArvo(1957); cout<<"Kopioidun olion tietoj\204sen:"<<endl; ekaAutoKopio.HaeArvo(); cout<<"Alkuper\204isen olion tietoj\204senen arvo lopuksi:"<<endl; ekaAutoAlkup.HaeArvo(); return 0; }

37 Olioon kohdistuvia perustoimintoja tMyn37


Lataa ppt "Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan."

Samankaltaiset esitykset


Iklan oleh Google