Olio-ohjelmoinnin perusteet luento 2

56
Olio-ohjelmoinnin perusteet luento 2 Päivi Ovaska LTKK/Tietotekniikan osasto

description

Olio-ohjelmoinnin perusteet luento 2. Päivi Ovaska LTKK/Tietotekniikan osasto. Sisältö. Yleistä olio-ohjelmoinnista Olio-ohjelmoinnin osat Luokat ja kapselointi Luokkien muodostaminen Luokkien tuhoaminen. Yleistä olio-ohjelmoinnista. - PowerPoint PPT Presentation

Transcript of Olio-ohjelmoinnin perusteet luento 2

Page 1: Olio-ohjelmoinnin perusteet luento 2

Olio-ohjelmoinnin perusteetluento 2

Päivi OvaskaLTKK/Tietotekniikan osasto

Page 2: Olio-ohjelmoinnin perusteet luento 2

Sisältö

Yleistä olio-ohjelmoinnista Olio-ohjelmoinnin osat Luokat ja kapselointi Luokkien muodostaminen Luokkien tuhoaminen

Page 3: Olio-ohjelmoinnin perusteet luento 2

Yleistä olio-ohjelmoinnista Olio-ohjelmointi tapa ajatella ja suunnitella ohjelma, ei

vain oliokielen kayttamista Oliokieli ei takaa olioajattelua Olio-ohjelmointi mahdollista muulla kuin oliokielella

(Yksi) ero ”perinteiseen ohjelmointiin”: Perinteinen: painopiste tietorakenteissa ja

algoritmeissa Oliot: painopiste ongelman jakamisessa

osakokonaisuuksiin, joilla omat vastuunsa ja jotka kommunikoivat keskenään

Sopii hyvin sekä top-down että bottom-up -suunnitteluun

Olennaista suunniteltavan järjestelmän käyttäytymisen ymmärtäminen

Page 4: Olio-ohjelmoinnin perusteet luento 2

Suurten ohjelmistokokonaisuuksien hallinta Ongelman jakaminen yhden ihmisen hallittaviin

paloihin ja yksinkertaistaminen abstrahoimalla Abstraktio: Ajatustoiminta, jonka avulla jostakin

käsitteestä saadaan yleisempi käsite vähentämällä siitä tiettyjä ominaisuuksia. Myös valikointi, jossa jokin ominaisuus tai ominaisuusryhmä erotetaan muista yhteyksistään tarkastelun kohteeksi

Abstrahoida: Suorittaa abstraktio, erottaa mielessään olennainen muusta yhteydestä

Abstrakti: Abstrahoimalla saatu, puhtaasti ajatuksellinen, käsitteellinen

Page 5: Olio-ohjelmoinnin perusteet luento 2

Esimerkki abstraktiosta

“Tiedon tallentaminen massamuistilaitteelle” Sovellusohjelmoijan ei tarvitse tuntea

kiintolevyn valmistajan käyttämää laitteen ohjauksen protokollaa, koodausta, ajoitusta ja bittien järjestystä, vaan hän voi käyttää erikseen määriteltyjä korkeamman(abstraktio) tason operaatioita (open, write, close)

Page 6: Olio-ohjelmoinnin perusteet luento 2

Oliopohjainen logiikka Ohjelmiston ylimmän tason logiikka voidaan määritellä

olioiden rajapintojen ja olioiden välisen kommunikaation avulla

Esimerkki: Shakkinappulaolio pyytää shakkilautaa mallintavalta oliolta tietoa siitä, voiko se siirtyä

määrättyyn ruutuun. Kyselyn seurauksena lautaolio voi taas vuorostaan kysyä muilta nappuloilta niiden nykyisiä paikkoja jne.

Shakkilaudan logiikka UML sekvenssikaaviona

: s h a kkin a p p u la : s h a kkila u ta

v o iko -s iirty ä -ru u tu u n X

:n a p p u la

o le tko ru u d u s s a X

Page 7: Olio-ohjelmoinnin perusteet luento 2

Oliot ja luokat Olio on itse vastuussa omien tietojensa käsittelystä

omien toimenpiteidensä avulla Oliot ryhmitellään luokkiin Luokka määrittelee, mitä tietoja olioilla on ja mitä

toimintoja luokan oliot osaavat Oliot suorittavat näitä toimintoja saadessaan toisilta

olioilta palvelupyyntöjä Tietojen ja toimintojen yhdistämisellä pyritään

helpottamaan ohjelmiston osien ylläpidettävyyttä ja uudelleenkäytettävyyttä

Luokat ovat uudelleenkäytettäviä komponentteja

Page 8: Olio-ohjelmoinnin perusteet luento 2

Olio-ohjelmoinnin näkökulmat valmiiden luokkien hyödyntäminen

Valmiiden luokkien hyödyntäminen tarkoittaa luokkakirjaston käyttöä. Valmiita luokkia käyttäessään ohjelmoija voi luoda olioita luokkiin ja käyttää olioita pyytämällä niiltä palvelua. Ohjelmoijan on siis tunnettava luokkakirjaston luokkarakenne ja kunkin luokan vastuulla oleva palvelut.

uudelleenkäytettävien luokkien tuottaminen Uudelleenkäytettävien luokkien tuottaminen

tarkoittaa luokkakirjaston rakentamista ja täydentämistä. Tällöin olemassaolevia komponentteja voidaan koota valmiista testatuista komponenteista tuottamalla mahdollisimman vähän uutta ohjelmakoodia.

Page 9: Olio-ohjelmoinnin perusteet luento 2

Oliot ja komponentit Oliokeskeinen ohjelmisto on toistensa kanssa

vuorovaikutuksessa toimivien komponenttien kokoelma.

Esim. Kokoonpanoteollisuus (autot, mikrot, viihde-elektroniikka): Tehdas ostaa komponentit ja kokoaa tuotteen valmiista komponenteista. Komponentteja hyödyntäviltä kokoajilta vaaditaan komponenttien liittämistaito ja komponentteja valmistavilta vaaditaan yksityiskohtaista tietoutta komponenttien valmistamisesta

Olio-ohjelmointia voisi kutsua tällä perusteella kokoonpano-ohjelmoinniksi!

Page 10: Olio-ohjelmoinnin perusteet luento 2

Mitä on olio-ohjelmointi? Oliot ja niiden kommunikointi

(Objects and communication) Luokat (Classes) Kapselointi (Encapsulation) Periytyminen (Inheritance) Monimuotoisuus (Polymorfism) Geneeriset/parametrisoidut tyypit (generic or parameterized types)

Page 11: Olio-ohjelmoinnin perusteet luento 2

Oliot ja niiden kommunikointi Olio (object) on tietojen ja palvelujen kokonaisuus. Olio on

ohjelman toteutuksen kannalta ajonaikainen keskusmuistista tehty tilanvaraus.

Viesti (message) on oliolle lähetetty pyyntö suorittaa jonkin olion vastuulla oleva palvelu.

Viesti on olioiden kommunikointitapa. Ohjelman toteutuksen kannalta viesti on olion kautta tapahtuva luokan aliohjelman kutsu.

Palvelu (service) on olion asiakasolioilleen tarjoama ja olion vastuulla oleva tehtävä. Toteutuksen kannalta palvelu on luokan aliohjelman esittely

Olio voi olla jokin tietty yritys, tuote, päivämäärä, käyttäjä, kokonaisluku jne. Oliot voivat olla siis eri abstraktiotasolla. Yhteistä olioille on se, että kullakin oliolla on vastuullaan omat tietonsa ja niiden käsittelyyn tarvittavat palvelut.

Page 12: Olio-ohjelmoinnin perusteet luento 2

Tiedon piilotus Oliolähestysmistavassa eräs keskeinen periaate on

tiedon piilotuksen (information hiding) periaate Tämä tarkoittaa sitä, että vain olio itse voi käsitellä

omia tietojansa. Olio ei siis näe toisen olion tietoja eikä kykene niitä käsittelemään.

Tiedon piilotus mahdollistaa olion käytön komponenttina, joka on mahdollista liittää muihin komponentteihin tietämättä sen sisältöä. Ainoastaan komponentin käyttötarkoitus ja ulkoinen rajapinta on tiedettävä, jotta oliota voisi käyttää

Ulkoinen rajapinta sisältää olion palvelut.

Page 13: Olio-ohjelmoinnin perusteet luento 2

Luokat tai tyypit Luokka (class) on olioiden tyyppi. Joissakin oliokielissä

sitä kutsutaankin tyypiksi (type) . Jokainen olio kuuluu luokkaan. Olio on luokkansa ilmentymä. Toteutuksen kannalta luokka on ohjelmoijan määrittelemä tyyppi

Attribuutti (attribute) on luokassa määriteltävä luokan olion ominaisuutta kuvaileva tieto. Toteutuksen kannalta attribuutti on luokassa määriteltävä tieto. C++ vastine tietojäsen (data member)

Palvelu (service) on luokassa esitelty luokan olioiden vastuulla oleva tehtävä. Toteutuksen kannalta palvelu on luokkaan liitetyn aliohjelman esittely.

Metodi (method) on palvelun toteutustapa. Toteutuksen kannalta metodi on luokkaan liittetty aliohjelma. C++ vastine aliohjelmajäsen (function member)

Page 14: Olio-ohjelmoinnin perusteet luento 2

Kapselointi (Encapsulation) Kapseloinnissa yhdistetään tietotyyppin

tietorakenne ja sen toiminnot. Samalla kätketään tietotyypin sisäinen rakenne ja toimintojen toteutus.

Kapseloinnilla pakotetaan ohjelmoija käyttämän olion käsittelyssä vain sen tyyppiin kuuluvia menetelmiä.

Kapseloinnilla pienennetään muutos- ja ylläpitokustannuksia

Page 15: Olio-ohjelmoinnin perusteet luento 2

Esimerkki tietotyypin vs. luokan käyttö Tietotyypin käyttö:Kokonaisluku muuttuja; muuttujan tilanvarausmuuttuja = 2; tyyppiin liitetyn

toimenpiteen käyttö

cout<< “Luku on: “ <<luku ; muuttujan sisältöön viittaus

Luokan käyttöPäivämäärä päivä; päivä-olion

tilanvarauspäivä = 1.1.1997; luokkaan liitetyn

palvelun käyttöpäivä.Näytä; luokkaan liitetyn

palvelun käyttö

Page 16: Olio-ohjelmoinnin perusteet luento 2

Erilaisia olioita Kohdeoliot liittyvät kohdealueen liiketoiminnan

ilmiöihin, esim. asiakas ja tilaus Liittymäoliot huolehtivat eri järjestelmien välisestä

kommunikoinnista, esim. käyttöliittymäoliosta ikkuna ja painike

Perustieto-oliot, joita käytetään muiden luokkien koostamisessa, esim. päivämäärä

Tekniset oliot voivat olla toteutusvälineen tarjoamia apuvälineitä tai vaikkapa ajonaikaisia muiden olioiden keskusmuistiosoitteista kirjaa pitäviä tietorakenneolioita

Tietovarasto-oliot huolehtivat tietoja sisältävien pysyvien olioiden talletuksesta tietovarastoon

Ohjausoliot liittyvät tiettyyn tehtävään ja liittävät yhteen ko. tehtävässä tarvittavia olioita

Page 17: Olio-ohjelmoinnin perusteet luento 2

Luokka Luokka (class) on ohjelmoijan määrittelemä tyyppi,

jonka avulla kapselointi toteutetaan Luokka on abstraktin tietotyypin (ADT, Abstract

data type) toteutus liittää tyyppiin kuuluvat attribuutit (tietojäsen,

data member) ja attribuutteja käsittelevät metodit (aliohjelmajäsen, function member) yhteen

Luokkien käyttöön liittyvät aiheet ovat: luokkatyypin määrittely luokkatyypin aliohjelmien toteutus luokkatyypin palveluiden käyttö olioiden avulla olioiden luonti eli tilanvaraus ja tuhoaminen eli

tilanvapautus viestin välitys oliolle

Page 18: Olio-ohjelmoinnin perusteet luento 2

Esimerkki struct luokasta#include <iostream>using namespace std;struct Luku{

int luku;};int main(){

Luku tietue;cout<<"\nSyötä luku: ";cin>>tietue.luku;cout<<"Syöttämäsi luku on: "<<tietue.luku;return 0;

} struct-määreellä määritellyn luokan jäsenet ovat julkisia

Page 19: Olio-ohjelmoinnin perusteet luento 2

Esimerkki class luokasta#include <iostream.h>class Luku{

int luku; //yksityinen jäsenpublic: //public määreen jäljessä on luokan julkiset palvelut

void kysy();void nayta();

};void Luku::kysy() //luokan aliohjelmajäsen, joka käsittelee

//luokan tietojäseniä{

cout<<"\nSyötä luku: ";cin>>luku;

}void Luku::nayta() //luokan aliohjelmajäsen, joka käsittelee

//luokan tietojäseniä{

cout<<"\nSyöttämäsi luku on: "<<luku;}int main(void){

Luku Olio;Olio.kysy(); Olio.nayta();return 0;

} class-määreellä määritellyn luokan jäsenet ovat oletusarvoisesti yksityisiä eli ne näkyvät vain luokan omissa

aliohjelmissa

Luku- luokkaUML luokkakaaviona

C la s s Lu k u

lu ku :in t

ky s y ():v o idn a y ta ():v o id

Page 20: Olio-ohjelmoinnin perusteet luento 2

Luokka Luokan julkiset palvelut muodostavat luokan liittymän

(interface) luokan asiakkaisiin Luokkatyypin määrittely tarkoittaa luokan tietojäsenten ja

aliohjelmajäsenten esittelyä. Ei varaa muistia olion talletusta varten

Luokan määrittely muotoa:luokan_tyyppi luokan_nimi{tietojäsenten esittelyaliohjelmajäsenten esittely};

luokan_tyyppi class, struct, union tietojäsenet voivat olla mitä tahansa tyyppiä olevia

tietoja tai olioita aliohjelmajäsenet ovat tietojäseniä käsittelevien

aliohjelmien esittelyitä

Page 21: Olio-ohjelmoinnin perusteet luento 2

Luokan jäsenten näkyvyys

Luokan jäsenten näkyvyyteen voidaan vaikuttaa luokkatyyppien struct ja class yhteydessä varatuilla sanoilla private, protected ja public (=saantimääreitä, access specifiers)private=yksityinenpublic=julkinen protected=suojattu, liittyy periytymiseen,

tiedot näkyvät myös aliluokissa

Page 22: Olio-ohjelmoinnin perusteet luento 2

Luokkien nimeämiskäytännöstä Nimeämisellä huomattava vaikutus luokkien käytettävyyteen Luokan nimi: aloitetaan suurella kirjaimella Luokan tietojäsenen nimi: aloitetaan pienellä kirjaimella, jos tietojäsen on tavallinen

muuttuja ja suurella kirjaimella, jos tietojäsen edustaa oliota Luokan aliohjelman nimi: aloitetaan pienellä kirjaimella Luokan aliohjelman nimen tulisi muistuttaa aliohjelman tarjoamasta palvelusta Luokan julkiset palvelut muodostavat luokan “julkisivun”, liittymän olisi oltava

mahdollisimman edustava ja selkeä Luokan määrittely toimii samalla luokan esittelynä, mutta joskus on tarpeen esitellä

luokka ilman tietojäsenten ja aliohjelmajäsenten esittelyä (kun kaksi luokkaa sisältävät viittauksia ristikkäin toisiinsa)

class Auto;class Omistaja{

Auto* Auto_olio;char omistajannimi20;...

};class Auto{

Omistaja* Omistaja_olio;char rekisteri8;...

};

Page 23: Olio-ohjelmoinnin perusteet luento 2

Luokan metodit ja viestit Luokan aliohjelman toteutus eli metodi:

tyyppi luokan_nimi::aliohjelman_nimi (parametrit){

aliohjelman runko}

Viestin lähettäminen luokkaan luodulle oliolle on luokan aliohjelman kutsu. Aliohjelma käsittelee sen olion tietojäseniä, jolle viesti on saapunut. Eri kutsukerroilla sama aliohjelma siis käsittelee eri olioiden tietojäseniä. Mistä aliohjelma tietää, minkä olion tietoja se käsittelee, kun aliohjelmassa viitataan tietojäseniin ilman erityistä olion tunnusta?

C++-kielessä this-osoitin sisältää viestin saaneen olion keskusmuistiosoitteen. This-osoitinta voidaan käyttää luokkaan kuuluvissa aliohjelmissa.

this-osoitin on valmiiksi esitelty:

Luokan_nimi* const this; //this-osoitin on vakio-osoitin

Page 24: Olio-ohjelmoinnin perusteet luento 2

this-osoitin esimerkkiclass X{

int m;public:

int readm() {return this->m;} //ei välttämätöntä, return m myös ok.

Käytetään yleensä aliohjelmissa, joissa käytetään osoittimia suoraanclass dlink{

dlink* pre; //edellinendlink* suc; //seuraava

public:void append(dlink*);

.....}void dlink::append(dlink* p){

p->suc = suc;p->pre = this;suc->pre =p;suc = p;

}

Page 25: Olio-ohjelmoinnin perusteet luento 2

Luokan käyttäminen olioiden kautta Asiakasolio lähettää palvelupyynnön eli viestin

palvelinoliolle, joka sitten suorittaa palveluun liittyvän metodin ja/tai delegoi edelleen palvelupyynnön jollekin toiselle oliolle

Asiakasoliolla on oltava tiedossaan palvelinolion tunnus, jonka se voidaan saada haltuunsa:

Palvelinolion tunnus näkyy oliolle globaalisti tai nimiarvaruutensa perusteella

palvelinolion tunnus on talletettu tietojäsenen sisällöksi

asiakasolio luo uuden palvelinolion asiakasolion aliohjelma saa palvelinolion

tunnuksen parametrina oma asiakasolioltaan (palvelupyynnön delegointi)

Page 26: Olio-ohjelmoinnin perusteet luento 2

Esimerkki delegoinnista Henkilö-luokan olio delegoin tehtävän parametrina saadulle Osasto-oliolle#include <iostream>using namespace std;class Osasto{...public:

void Nayta();};class Henkilo{...public:

void KysyOsastolta(Osasto &);};

void Henkilo::KysysOsastolta(Osasto& Olio_osasto){ .. Olio_osasto.Nayta();

}

...int main(){

Henkilo Eka; Osasto Olio_osasto; ... Eka.KysyOsastolta(Olio_osasto);

Page 27: Olio-ohjelmoinnin perusteet luento 2

Viestinvälityksen suunnittelu käyttäen UML sekvenssikaaviota

Esim. herätyskellon sekvenssikaavio

: O h ja u s : S o it to y ks ikko

:Us e r

p a in a _ h a ly ty s ()

lo p e ta _ s o it to ()

a lo it a _ s o it to ()

Page 28: Olio-ohjelmoinnin perusteet luento 2

main-ohjelman rooli luokkien käyttäjänä

#include <iostream.h>#include “sovellus.hpp” int main(){

Sovellus Sovellusolio; //olion tilanvarausSovelluolio.aja(); //olion palvelupyyntöreturn 0;

}

Page 29: Olio-ohjelmoinnin perusteet luento 2

Luokan jäsenet

class luokan_nimi{

tyypit: enum, struct, class, typedeftiedot: staticaliohjelmat: static, inline, const, virtualystävät: friend

}; Luokassa esiteltävät tietojäsenet voivat olla

oliokohtaisia tai luokkakohtaisia

Page 30: Olio-ohjelmoinnin perusteet luento 2

Luokan oliokohtaiset tietojäsenet Olion muistinvarausluokan mukaiset tietojäsenet Käyttö: olion tilatiedot, pakolliset koostumussuhteet Elinikä: samanikäisiä kuin olion tunnus

#include <iostream>class Merkkijono{

char jono25;...

};int main(void){

Merkkijono Automaattinen;Merkkijono *Dynaaminen=new Merkkijono;...

delete Dynaaminen;return 0;

}

Page 31: Olio-ohjelmoinnin perusteet luento 2

Luokan dynaamiset tietojäsenet Käyttö: olion tilatiedot, ehdolliset tai pakolliset koostumus- ja yhteyssuhteet Toteutustapa: osoittimet Elinikä: ohjelmoija päättää tilanvarauksen ja -vapautuksen ajankohdan

#include <iostream>class Merkkijono{

char* jono;...

};int main(void){

Merkkijono Automaattinen;Merkkijono *Dynaaminen=new Merkkijono;...delete Dynaaminen;return 0;

} Kun oliolle vartaan tila, tulee automaattisesti varatuksi osoitinmuuttujan tarvitsema

tila, mutta ei merkkijonon vaatimaa muistitilaa. Ohjelmoijan on itse tehtävätilanvaraus ja -vapautus olion dynaamisille tietojäsenille luokan aliohjelmissa. Kun olion tila vapautuu, häviää osoitinmuuttujan jono tilanvaraus automaattisesti, mutta ei jono-osoittimen osoittaman muistialueen tilanvaraus

Page 32: Olio-ohjelmoinnin perusteet luento 2

Luokan luokkakohtaiset tiedot Käyttö: luokkaa kuvailevat tiedot, kaikki oliot voivat käyttää Elinikä: staattinen, ei riipu luokan olioiden eliniästä Toteutustapa: esittely varatulla sanalla static

#include <iostream>class Merkkijono{

char jono25;static int lkm;...

};int main(void){

Merkkijono Automaattinen;Merkkijono *Dynaaminen=new Merkkijono;...delete Dynaaminen;return 0;

}

Page 33: Olio-ohjelmoinnin perusteet luento 2

Luokan aliohjelmajäsenet Oliokohtaisia tietoja käsittelevät aliohjelmat

muodostimet (constructor): olion alustus ja kopiointi olion tilanvarauksen yhteydessä

hajotin (destructor): olion tyhjennys ja tilanvapautus sijoitusoperaattori=: alustus tilanvarauksen jälkeen muut ohjelmoijan määrittelemät aliohjelmat inline, const, virtual

Luokkakohtaisia tietoja käsittelevät aliohjelmat: static, voidaan käyttää lisämääreitä inline ja const

class Luokka{tyyppi aliohjelma1() {...} // inline-aliohjelman runko

toteutettu suoraan esittelyn

yhteyteeninline tyyppi Luokka::aliohjelma2() //runko toteutettu

//erikseen{...}

Vakioaliohjelma ei voi muuttaa olion tietojatyyppi aliohjelma(parametrit) const;

Page 34: Olio-ohjelmoinnin perusteet luento 2

Vakio-oliot Vakio-olion parametrina saanut aliohjelma ei voi

kutsua vakio-olion kautta muita kuin luokan vakioaliohjelmia

#include <iostream>class Henkilo...public:

char* etunimi() const; void vaihdaEtunimi(const char*);

};void aliohjelma(Henkilo& Olio1, const Henkilo& Olio2){

Olio1.vaihdaEtunimi(“Maija”);cout<<Olio2.etunimi();

}

Page 35: Olio-ohjelmoinnin perusteet luento 2

Olion luonti eli tilanvaraus

Olion esittely liittää tunnuksen nimen olion tyyppiin eli luokkaan

Olion määrittely luo olion eli määrittely varaa keskusmuistitilan olion tiedoille

Page 36: Olio-ohjelmoinnin perusteet luento 2

Olioiden muistinvarausluokat: Automaattinen olio on paikallinen lohkossa järjestelmä varaa oliolle keskusmuistitilan olion määrittelyn

yhteydessä pinosta järjestelmä vapauttaa oliolle varatun keskusmuistitilan

automaattisesti lohkon loppuessa esittely ja määrittely:

Luokan_nimi Olion_tunnusHenkilo Hlo_olio;

Ovat olemassa tietyn palveluketjun tai metodin suorituksen ajan

Käytetään väliaikaisina työolioina, kun käsiteltävien olioiden lukumäärä on tiedossa ohjelman kirjoitusvaiheessa ja kun olion ei tarvitse olla olemassa sen luoneen ohjelmalohkon loputtua

Page 37: Olio-ohjelmoinnin perusteet luento 2

Olioiden muistinvarausluokat: Dynaaminen ohjelmoija varaa oliolle keskusmuistitilan new-

operaattorilla vapaasta muistista eli keosta ohjelmoija vapauttaa tilan delete-operaattorilla olioiden tilanvaraus ei häviä automaattisesti, vaan

ohjelmoijan on vapautettava tila Esittely ja määrittely erikseen:

Luokan_nimi* Olion_tunnus; //osoitinmuuttujan esittelyOlion_tunnus = new Luokan_nimi ///tilanvarausHenkilo * Hlo_olio;Hlo_olio = new Henkilo;

Esittely ja määrittely yhtäaikaisesti:Luokan_nimi* Olion_tunnus = new Luokan_nimiHenkilo* Hlo_olio=new Henkilo;

Hlo_olio on osoitinmuuttuja, joka sisältää osoitteen oliolle varatun keskusmuistialueen alkuun

tarvitaan osoittimia ja dynaamista muistinhallintaa

Page 38: Olio-ohjelmoinnin perusteet luento 2

Olioiden muistinvarausluokat: Dynaaminen Olion tilanvapautus:

delete Olion_tunnus;void aliohjelma(void){

Henkilo Hlo_olio1;Henkilo* Hlo_olio2 = new Henkilo;static Henkilo Hlo_olio;....delete Hlo_olio2;

} Oliotaulukon vapautus:

delete Oliot;Henkilo* Oliot = new Henkilo5;...delete Oliot;

Page 39: Olio-ohjelmoinnin perusteet luento 2

Olioiden muistinvarausluokat:Staattinen olio voi olla globaali tai static-määreellä esitelty paikallinen olio järjestelmä varaa oliolle keskusmuistitilan pääohjelman käynnistyksen

yhteydessä järjestelmä vapauttaa oliolle varatun keskusmuistitilan pääohjelman

loppuessa Esittely ja määrittely:

static Luokan_nimi Olion_tunnus;static Luokan_nimi* Olion_tunnus = new Luokan_nimi;{

static Henkilo Hlo_olio1;static Henkilo* Hlo_olio2; Hlo_olio2=new Henkilo;

} Staattiset oliot ovat olemassa koko sovelluksen käyttöajan Staattiset oliot sisältävät usein sovellukseen, palveluketjuun tai

luokkaan liitttyvää kirjanpito- tms. tietoa, jonka tulee olla käytettävissä aina

Page 40: Olio-ohjelmoinnin perusteet luento 2

Viestin välitys oliolle Viesti on luokan aliohjelman kutsu Viestin välitys automaattiselle oliolle:

Olion_tunnus.Aliohjelman_nimi(); Viestin välitys dynaamiselle oliolle:

if (Olion_tunnus)Olion_tunnus->aliohjelman_nimi();

Henkilo Olio1;Henkilo* Olio2=new Henkilo;Olio1.kysy();Olio1.nayta();if (Olio2) Olio2->kysy();if (Olio2) Olio2->nayta();delete Olio2;

Page 41: Olio-ohjelmoinnin perusteet luento 2

Olioiden luonti Olion luontiin liittyvät vaiheet:

olion tilanvaraus olion alustus

Olion alustus tapahtuu tilanvarauksen yhteydessä Alustus muodostin (constructor) -aliohjelmassa Muodostimia kolmenlaisia:

oletusmuodostin (default constructor) olion tietojäsenten alustus oletusarvoilla kopiointimuodostin (copy constructor) olion tietojäsenten alustus toisesta oliosta kopioimalla parametrilliset muodostimet

olion tietojäsenten alustus ohjelmoijan tapauskohtaisesti määräämillä alkuarvoilla

Luokkaan määritellään muodostimia, jotta voitaisiin varmistaa, että olion tietojäsenet ovat alustettuja ja että ohjelma ei keskeydy ajonaikaiseen virheeseen tietojäsenen sisältöön viitattaessa

Järjestelmä kutsuu muodostinta automaattisesti olion tilanvarauksen yhteydessä

Page 42: Olio-ohjelmoinnin perusteet luento 2

Oletusmuodostin (default constructor) Järjestelmä kutsuu oletusmuodostina automaattisesti olion tilanvarauksen yhteydessä

Luokka Olio; //automaattinen muodostimen kutsuLuokka Olio = Luokka(); //ohjelmoijan mudostimen kutsuLuokka *Olio=new Luokka;LUOkka *Olio=new Luokka();

Oletusmuodostimen esittelyclass Luokka{...public:

Luokka(); //oletusmuodostin};

Oletusmuodostimen määrittely eli toteutus:Luokka::Luokka(): tietojäsenten alustukset //joko näin{

tietojäsenten alustukset //tai näinmuodostimen runko

} Tietojäsenten alustus muodostimen 1. rivillä

Luokka::Luokka(): tieto(lauseke), tieto(lauseke),...{}

tieto:alustettava tietojäsenlauseke: muuttuja, vakio tai jokin muu lauseke, jonka arvolla tietojäsen alustuu

jos alustuslauseke yksinkertainen jos alustettava tietojäsen esitelty vakioksi const jos alustettava tietojäsen on viittausmuuttuja

Page 43: Olio-ohjelmoinnin perusteet luento 2

Esimerkki oletusmuodostimesta#include <iostream>Using namespace std;class Pvm{

int pp, kk, vv;public:

Pvm();void nayta() const;

};Pvm::Pvm() : pp(1), kk(2), vv(96){}void Pvm::nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

Pvm Paiva;Paiva.nayta();return 0;

}

Page 44: Olio-ohjelmoinnin perusteet luento 2

2. esimerkki oletusmuodostimesta Tietojäsenten alustus muodostimen rungossa:

Luokka::Luokka(){

tieto = lauseke;...

}#include <iostream>#include <time>class Pvm{

int pp, kk, vv;public:

Pvm();void nayta() const;

};Pvm::Pvm(){

time_t sek;tm *paiva;time(&sek);paiva = localtime(&sek);pp = paiva->tm_mday;kk = paiva->tm_mon + 1;vv = paiva->tm_year;

}void Pvm::nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

Pvm Paiva;Paiva.nayta();return 0;

}

Page 45: Olio-ohjelmoinnin perusteet luento 2

Parametrillinen muodostin Jos ohjelmoija haluaa alustaa oliot tilanvarauksen

yhteydessä tapauskohtaisilla alkuarvoilla Parametrillinen muodostin on aina ohjelmoijan

kirjoittama Samat säännöt kuin oletusmuodostimella Poikkeuksia: Parametrillisen muodostimen parametreihin voidaan

määritellä tarvittaessa myös oletusarvot Luokka voi sisältää useita erilaisilla parametreilla

varustettuja muodostimia Kääntäjä ei generoi oletusmuodostimia, jos

ohjelmoija on määritellyt luokkaan parametrillisen muodostimen

Page 46: Olio-ohjelmoinnin perusteet luento 2

Parametrillinen muodostin esimerkki 1

#include <iostream>#include <time>class Pvm{

int pp, kk, vv;public:

Pvm(const int, const int, const int); //parametrillinen muodostinvoid nayta()const;

};Pvm::Pvm(const int p_pp, const int p_kk, const int p_vv): pp(p_pp), kk(p_kk), vv(p_vv){}void Pvm::nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

Pvm Paiva(3, 3, 96); //Paiva-olion luonti ja alustusPaiva.nayta();return 0;

}

Page 47: Olio-ohjelmoinnin perusteet luento 2

Parametrillinen muodostin esimerkki 2

#include <iostream>class Pvm{

int pp, kk, vv;public:

Pvm(const int, const int, const int = 96);void nayta() const;

};Pvm::Pvm(const int p_pp, const int p_kk, const int p_vv){

pp = p_pp;kk = p_kk;vv = p_vv;

}void Pvm::nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

Pvm Paiva1(1, 2);Pvm Paiva2(3, 3, 97);cout<<"Päivä1: ";Paiva1 Paiva2.nayta();return 0;

Paiva2.Nayta();cout<<"\nPäivä2: ";

}

Page 48: Olio-ohjelmoinnin perusteet luento 2

Kopiomuodostin (copy constructor) alustaa olion tietojäsenet saman luokan olemassa olevan olion tiedoilla Automaattisen olion tilanvaraus ja kopiointimuodostimen kutsu:

Luokka Uusi_olio(Vanha_olio); //Vanha_olio automaattinenLuokka Uusi_olio = Vanha_olio; // “Luokka Uusi_olio(*Vanha_olio); // Vanha_olio dynaa,omemLuokka Uusi_olio = *Vanha_olio // “

Dynaamisen olion tilanvaraus ja kopiontimuodostimen kutsu:Luokka* Uusi_olio;Uusi_olio=new Luokka (Vanha_olio);//Vanha_olio automaattinenUusi_olio=new Luokka (*Vanha_olio); //Vanha_olio dynaaminen

Pvm Paiva1(1,2,96); Pvm Paiva2(Paiva1);Pvm* Paiva3=new Pvm(Paiva1);Pvm* Paiva4=new Pbm(*Paiva3);Pvm Paiva5(*Paiva3);Pvm Paiva6=Paiva5;

Ohjelmoija voi määritellä itse kopiointimuodostimen Kopiointimuodostimen esittelytavat:

Luokka (const Luokka &);Luokka (const Luokka &, parametri = alkuarvo, …);

Page 49: Olio-ohjelmoinnin perusteet luento 2

Kopiomuodostin (copy constructor)

#include <iostream>#include <time>class Pvm{

int pp, kk, vv;public:

Pvm(const int, const int);Pvm(const Pvm &, const int = 96);//kopiomuodostimen esittelyvoid nayta() const;

};Pvm::Pvm(const int p_pp, const int p_kk) :

pp(p_pp), kk(p_kk) {

time_t sek;tm *paiva;time(&sek);paiva = localtime(&sek);vv = paiva->tm_year;

}

}Pvm::Pvm(const Pvm &p_pvm, const int p_vv) :

pp(p_pvm.pp), kk(p_pvm.kk){

vv = p_vv;}void Pvm::nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

Pvm Paiva1(1, 2);Pvm Paiva2(Paiva1);//olion luonti kopiomuodostinta käyttäenPvm Paiva3(Paiva1, 97);cout<<"Päivä1: ";Paiva1.nayta();cout<<"\nPäivä2: ";Paiva2.nayta();cout<<"\nPäivä3: ";Paiva3.nayta();return 0;

}

Page 50: Olio-ohjelmoinnin perusteet luento 2

Sijoitus olioon sijoitusoperaattorilla Sijoitus toimi samalla tavalla kuin kopiointimuodostin:

sijoitettavan olion tietojäsenten sisällöt kopioituvat vastaanottavan olion tietojäsenten sisällöksiPaiva1 = Paiva2;Paiva1 = *Paiva2;*Paiva1 = Paiva2;*Paiva1 = *Paiva2;Paiva3 = *Paiva2 = Paiva1;

Sijoitettavien olioiden on oltava samaa tyyppiä Kääntäjä generoi sijoitusta varten sijoitusaliohjelman Ohjelmoija voi kirjoittaa sijoitusaliohjelman itse (=

operaattorin ylikuormitus)

Page 51: Olio-ohjelmoinnin perusteet luento 2

Sijoitusoperaattorin esittely ja sijoitusaliohjelman toteutus Sijoitusaliohjelman esittely:

class Luokka{...public:

Luokka &operator=(Luokka&);};

Sijoitusoperaattorin toteutus:Luokka &Luokka::operator=(Luokka& p_olio){sijoitukset tietojäseniin...return (*this);}

Page 52: Olio-ohjelmoinnin perusteet luento 2

Sijoitusoperaattori esimerkki#include <iostream.h>#include <time.h>class Pvm{

int pp, kk, vv;public:

Pvm(const int, const int);Pvm(const Pvm &, const int = 96);Pvm &Pvm::operator=(const Pvm &);void Nayta() const;

};Pvm::Pvm(const int p_pp, const int p_kk) :

pp(p_pp), kk(p_kk){

time_t sek;tm *paiva;time(&sek);paiva = localtime(&sek);vv = paiva->tm_year;

}Pvm::Pvm(const Pvm &p_pvm, const int p_vv) :

pp(p_pvm.pp), kk(p_pvm.kk){

vv = p_vv;}

Pvm &Pvm::operator=(const Pvm &p_pvm){

pp = p_pvm.pp;kk = p_pvm.kk;vv = p_pvm.vv;return (*this);

}void Pvm::Nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

Pvm Paiva1(1, 2);Pvm Paiva2(1, 3);Pvm Paiva3(1, 4);Paiva3 = Paiva2 = Paiva1;cout<<"Päivä1: ";Paiva1.Nayta();cout<<"\nPäivä2: ";Paiva2.Nayta();cout<<"\nPäivä3: ";Paiva3.Nayta();return 0;

}

Page 53: Olio-ohjelmoinnin perusteet luento 2

Sijoituksen ja kopioinnin eroista

Pvm Olio1=Pvm(1,2); //parametrillinen muodostin

Pvm Olio2; //oletusmuodostimen kutsu

Olio2=Pvm(1,2); //parametrillinen muodostin ja sijoitus

Kääntäjäympäristöt eroavat toisistaanmuodostimien kutsuissa

Page 54: Olio-ohjelmoinnin perusteet luento 2

Olion tietojäsenten tyhjennys ja hajoitin Olion tuhoamiseen littyvät vaiheet:

olion tyhjennys olion tilanvapautus

Hajottimen tarkoituksena on tyhjentää olion tietojäsenet ja vapauttaa olion sisäiset rakenteet

Järjestelmä kutsuu hajotinta olion tilanvapautuksen yhteydessä automaattisesti

voidaan kutsua ohjelmallisesti myös ennen tilanvapautusta, kun olio halutaan väliaiakaisesti tyhjentää

Page 55: Olio-ohjelmoinnin perusteet luento 2

Hajotin Hajottimen nimi on ~Luokan_nimi Hajotin ei saa parametreja Hajottimella ei ole tyyppiä, ei saa palauttaa mitään arvoa Esittelyssä ei saa esiintyä varattuja sanoja const, volatile tai static Hajotin voi olla virtuaalinen (liittyy periytymiseen) Hajottimen kutsu:

Olio.Luokka:: ~Luokka();Olio->Luokka:: ~Luokka();

Hajottimen esittely:class Luokka...public:

~Luokka();};

Hajottimen määrittely:Luokka:: ~Luokka(){

tietojäsenten tyhjennys}

Page 56: Olio-ohjelmoinnin perusteet luento 2

Hajotin esimerkki#include <iostream.h>#include <time.h>class Pvm{

int pp, kk, vv;public:

Pvm(const int, const int);Pvm(const Pvm &, const int = 96);Pvm &Pvm::operator=(const Pvm &);~Pvm();void Nayta() const;

};Pvm::Pvm(const int p_pp, const int p_kk) : pp(p_pp),

kk(p_kk){

time_t sek;tm *paiva;time(&sek);paiva = localtime(&sek);vv = paiva->tm_year;

}Pvm::Pvm(const Pvm &p_pvm, const int p_vv) :

pp(p_pvm.pp), kk(p_pvm.kk){

vv = p_vv;}Pvm &Pvm::operator=(const Pvm &p_pvm){

pp = p_pvm.pp;kk = p_pvm.kk;vv = p_pvm.vv;return (*this);

}

Pvm::~Pvm(){

pp = 0;kk = 0;vv = 0;

}void Pvm::nayta() const{

cout<<pp<<'/'<<kk<<'/'<<vv;}int main(void){

cout<<"Päivä1: ";Pvm Paiva1(1, 2);Paiva1.Pvm::~Pvm();Paiva1.nayta();

cout<<"\nPäivä2: ";Pvm *Paiva2 = new Pvm(2, 2);Paiva2->Pvm::~Pvm();Paiva2->nayta();delete Paiva2;return 0;

}