400 likes | 565 Views
Olio-ohjelmointi 2. osa: diat 71-110 (2. välikoe). KYMENLAAKSON AMMATTIKORKEAKOULU Jarkko Ansamäki, 2001. Läpikäytävät asiat. Olioiden kommunikaatio Perintä ja olion koostuminen osaolioista Tiedostojen käsittely Virheiden käsittely Debuggaus Nopea tutustuminen Windows-ohjelmointiin.
E N D
Olio-ohjelmointi2. osa: diat 71-110 (2. välikoe) KYMENLAAKSON AMMATTIKORKEAKOULU Jarkko Ansamäki, 2001 KYAMK/J.Ansamäki/Olio-ohjelmointi
Läpikäytävät asiat • Olioiden kommunikaatio • Perintä ja olion koostuminen osaolioista • Tiedostojen käsittely • Virheiden käsittely • Debuggaus • Nopea tutustuminen Windows-ohjelmointiin. • Muuta? KYAMK/J.Ansamäki/Olio-ohjelmointi
Olioiden kommunikaatio • Viesti = oliolle lähetetty luokkaan kuuluvan aliohjelman (funktion) kutsu. • Aliohjelma käsittelee sen olion tietojäseniä, jolle kutsu on saapunut. • Eri kutsukerroilla sama aliohjelma voi siis käsitellä eri olioiden tietojäseniä. • Toteutuu this-osoittimen avulla. KYAMK/J.Ansamäki/Olio-ohjelmointi
this-osoitin • Osoitin on C++ kielessä valmiiksi esitelty: • Luokan_nimi *const this; • Osoitin pitää sisällään kutsutun olion muistiosoitteen. • void Luokka::Tulostus2(){ • cout<<”Traa: ”; this->Tulostus1(); } KYAMK/J.Ansamäki/Olio-ohjelmointi
this-osoittimen käyttö • Käytännössä this-osoittimella on kaksi käyttötarkoitusta: • Osoitinta voidaan käyttää viestinvälityksessä, jos esimerkiksi kutsuttava olio tarvitsee kutsuvan olion muistiosoitetta johonkin. • Osoitinta voidaan käyttää apuna testausvaiheessa kun halutaan esimerkiksi selvittää olioiden olemassaoloaikoja. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 16 • Toteuta Testi-luokka siten, että luokan oletusmuodostin ilmoittaa uuden olion syntymisestä muistipaikkaan sejase ja luokan tuhoaja ilmoittaa olion kuolemisesta muistipaikassa sejase. • Tee sitten seuraavanlainen pääohjelma: • void main(){ Testi eka, *toka; cout<<”\n”; • toka=new Testi; delete toka; cout<<”\n\n”; } KYAMK/J.Ansamäki/Olio-ohjelmointi
Olion palveluiden kutsuminen olion sisältä. • Luokassa määritellyt funktiot ovat suoraan käytettävissä muista luokan funktioista käsin. Esimerkiksi: • private: int a; void T(){ cout<<”Traa”; } • public: void A(int x){ a=x; } • void T2(){ T(); cout<<a; } • Myös funktioita voidaan siis sijoittaa private-näkyvyysalueelle (luokan sisäiseen käyttöön). KYAMK/J.Ansamäki/Olio-ohjelmointi
Toisen olion käsittely olion sisältä • Viestin saaneen olion lisäksi aliohjelmissa on mahdollista käsitellä myös parametrina välitetyn olion tietoja. • Olion välitys parametrina toteutetaan osoitin- tai viittausmuuttujan avulla. • Asiaa opiskellaan opettajajohtoisesti laadittavien esimerkkikoodien avulla. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 17 • Lisää Henkilo-luokkaan palvelu, joka tulostaa yhden valitun (esim. sukunimen perusteella) henkilön tiedot. • Muuta tietojen tulostus –palvelua niin, että se käyttää hyväkseen tätä uutta palvelua. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 18 • Lisää Henkilo-luokkaan palvelut, jotka palauttavat pyydetyn henkilön: • etunimen • sukunimen • osoitteen • puhelinnumeron… • Lisää Henkilo-luokkaan palvelu, jolla henkilön tietoja voi hakea esimerkiksi nimen perusteella. KYAMK/J.Ansamäki/Olio-ohjelmointi
Perintä • Perinnässä johdetaan olemassa olevasta (tai varta vasten periytettäväksi tehdystä) luokasta uusi tarkoitusperiin sopiva luokka. • Seuraavalla dialla yksinkertainen esimerkki julkisesta perinnästä. KYAMK/J.Ansamäki/Olio-ohjelmointi
Esimerkki perinnästä • #include <iostream.h> • class VanhaLuokka{ • int a; • public: • void Aseta(int x){ a=x; } • int Palauta(){ return a; } • }; • class UusiLuokka : public VanhaLuokka{ • public: • void Lisaa(int x){ Aseta(x+Palauta()); } • }; • void main(){ • UusiLuokka Oolio; • Oolio.Aseta(2); Oolio.Lisaa(3); • cout<<Oolio.Palauta(); • } KYAMK/J.Ansamäki/Olio-ohjelmointi
Huomioita esimerkkikoodista • class UusiLuokka : public VanhaLuokka{… • Kaksoispiste, sana public ja kantaluokan nimi ilmaisevat perintäsuhteen. Toinen harvinaisempi perintätapa on yksityinen (private) jota kurssilla ei (luultavasti) käsitellä. • UusiLuokan oliolla on käyttöoikeus VanhaLuokan julkisiin jäseniin, mutta esimerkiksi a:n käsittely suoraan ei onnistu vaan pelkästään julkisten palveluiden kautta. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 19 • Periytä VanhaLuokka-luokasta uusi luokka, jossa palveluina lisäksi • uuden luvun vähentäminen aikaisemmasta a:n arvosta. • vanhan a:n arvon kertominen syötteenä saatavalla luvulla. KYAMK/J.Ansamäki/Olio-ohjelmointi
Virtuaalifunktiot • virtual-sana kertoo funktion olevan virtuaalisen jäsenfunktion. • =0 –merkintä tarkentaa funktion puhtaaksi virtuaalifunktioksi (pure virtual function). • Puhtaita virtuaalifunktioita (abstraktit toiminnot) sisältävään luokkaan ei voi tehdä olioita, vaan luokasta on periytettävä uusia luokkia joissa määritellään virtuaalifunktioiden toteutus. KYAMK/J.Ansamäki/Olio-ohjelmointi
Esimerkkikoodi • #include <iostream.h> • class Lauseke{ • public: • virtual void Tulosta(ostream &) const = 0; • virtual double Arvo () const = 0; }; • class Ynnaa : public Lauseke{ • double eka, toka; • public: • Ynnaa(double x, double y) : eka(x), toka(y){} • void Tulosta (ostream &s) const { s<<eka<<"+"<<toka; } • double Arvo () const{ return(eka+toka); } }; • void main(){ • Lauseke *lauseke; • lauseke=new Ynnaa(2, 3); • lauseke->Tulosta(cout); • cout<<"="<<lauseke->Arvo(); } KYAMK/J.Ansamäki/Olio-ohjelmointi
Huomioita koodista (kantaluokka) • Funktiot ovat vakiofunktioita (const), koska ne eivät muuta lauseketta, jolle niitä kutsutaan. • Lauseke-luokka siis esittelee kaksi funktiota, mutta ei määrittele niille mitään toimintaa. • Tulosta-palvelulle määritellään parametrin arvoksi tulostusvirtaan osoittava muistiosoite. KYAMK/J.Ansamäki/Olio-ohjelmointi
Huomioita koodista (johdettu luokka) • Luokkaan on määritelty tarvittavat tietojäsenet (eka ja toka) • Perityssä luokassa määritellyille palveluille on kirjoitettu metodit. • Myös luokan muodostin määritellään • Huomaa arvojen kopioiminen ’otsikkorivissä’: • Ynnaa (double x, double y):eka(x),toka(y){…} KYAMK/J.Ansamäki/Olio-ohjelmointi
Huomioita koodista (käyttö) • Pääohjelmassa luotu osoitin kantaluokkaan. • Myös johdetun luokan olio on eräänlainen kantaluokkansa olio, joten tämä onnistuu. • Luodaan uusi Ynnaa-luokan olio. • Huomaa cout:n käyttö Tulosta-funktion kanssa. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 20 • Lisää äsken esiteltyyn esimerkkikoodiin luokat vähennys-, kerto- ja jakolaskua varten. • Testaa luokkien toiminta. KYAMK/J.Ansamäki/Olio-ohjelmointi
(epäpuhtaat) virtuaalifunktiot • Muillekin, kuin puhtaille virtuaalifunktioille voi kirjoittaa uuden merkityksen periytetyssä luokassa. • Johdetun luokan funktioiden lisäksi voidaan nyt kutsua myös kantaluokan funktioita kertomalla toteutuksessa halutun luokan nimi. KYAMK/J.Ansamäki/Olio-ohjelmointi
Esimerkkikoodi • #include <iostream.h> • class Yliluokka{ • int a; • public: • void Aseta(int x){ a=x;} • virtual int Palauta() { return a; } • }; • class Aliluokka:public Yliluokka{ • public: • int Palauta(){ return(Yliluokka::Palauta());}; • }; • void main(){ • Aliluokka juu; • juu.Aseta(2); • cout<<juu.Palauta(); • } KYAMK/J.Ansamäki/Olio-ohjelmointi
protected-näkyvyysalue • protected: -lohkossa olevat tietojäsenet ja funktiot ovat suojattuja. • protected-jäsenet ovat käytettävissä luokan sisällä ja luokasta johdetuissa luokissa. • protected-jäsenet eivät siis varsinaisesti ole osa luokan käyttöliittymää, koska ne eivät ole käytettävissä luokan ulkopuolella kuten public-jäsenet. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 21 • Lisää tehtävän 19 VanhaLuokka-luokkaan protected-näkyvyysalueeseen funktio Nollaus, joka asettaa a:n arvoksi nollan. • Lisää tämän jälkeen johonkin periytettyyn luokkaan Nollaa-palvelu, joka kutsuu Nollaus-funktiota ja testaa toiminta. • Mieti, voitko käyttää perintää henkilörekisteriohjelmassasi? KYAMK/J.Ansamäki/Olio-ohjelmointi
Osista kokonaisuus • Toinen hierarkkinen luokkien välinen suhde on koostumissuhde, jossa jonkin luokan jäseninä on jonkin toisen luokan olioita. • Esimerkiksi korttipakassa on 52 kortti-oliota, lentokoneessa 0-4 lentokoneenmoottori-oliota. • Toteutus käyttämällä toiseen luokkaan kuuluvia olioita (tieto)jäseninä. KYAMK/J.Ansamäki/Olio-ohjelmointi
#include <iostream.h> • class Osa{ • char nimi[20]; • public: • Osa(){ cout<<"Anna osan nimi: "; cin>>nimi; } • char *Palauta(){return nimi;} • }; • class Kokonaisuus{ • Osa eka, toka; • char nimi[20]; • public: • Kokonaisuus(){ cout<<"Anna kokonaisuuden nimi: "; cin>>nimi; } • void Tulostus(); • }; • void Kokonaisuus::Tulostus(){ • cout<<nimi<<":\n"<<eka.Palauta()<<endl<<toka.Palauta()<<endl<<endl; • } • void main(){ • Kokonaisuus juttu; • juttu.Tulostus(); • } KYAMK/J.Ansamäki/Olio-ohjelmointi
Osaolioiden käyttö • Yksinkertaisissa tapauksissa automaattiset oliot riittävät, mutta heti kun halutaan tehdä hieman monimutkaisempia asioita, täytyy siirtyä dynaamisen muistinhallinnan ja osoittimien käyttöön. • Osaolioiden luonti tarvittaessa. • Tarvittavien osaolioiden määrän epävarmuus • Muualla luotujen olioiden sitominen osaksi toista oliota. • Tutustuminen asiaan esimerkkikoodien avulla. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 22 • Tee olio Sana-luokkaan. Sana-luokka koostuu Kirjain-luokan olioista. Mieti mitä palveluita tarvitaan missäkin luokassa ja miten asiat toteutetaan, jotta olio olisi joustava ja käyttökelpoinen. • Pisteiden haalimista varten voit tehdä puhelinmuistioosi ystäväryhmäluokan, jonka oliot koostuvat useammasta henkilöluokan oliosta. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tiedostojen käsittely • Tällä kurssilla käsitellään kahta eri keinoa tiedostojen käsittelyyn: • fstream-kirjastoa: http://www.kyamk.fi/~zjaan/kurssit/o-o/tiedostot/siframes.htm • MFC-kirjastoista löytyvää Cfile-luokkaa. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 23 • Tutustu Visual Studion ohjeistuksesta CFilen käyttöön. Selvitä ainakin seuraavat asiat: • Tarvittava kirjasto. • Luokan tarjoamat palvelut. • Tiedoston avaus (ja tärkeimmät avausliput). • Tiedostoon kirjoitus. • Tiedostosta lukeminen. KYAMK/J.Ansamäki/Olio-ohjelmointi
Esimerkkiongelma • Toteutetaan ohjelma, jonka avulla voidaan kirjoittaa muutama rivi tekstiä tiedostoon tai lukea olemassa oleva tiedosto ja tulostaa tiedoston sisältö näytölle. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 24 • Mietitään yhdessä, miten puhelinmuistioiden levytallennukset kannattaisi toteuttaa. KYAMK/J.Ansamäki/Olio-ohjelmointi
Virheiden käsittely • Ajonaikaisia C++ -ohjelman virhetilanteita voi käsitellä poikkeusten (exception) avulla. • MFC on tuonut jotain uusia keinoja poikkeusten hallintaan, mutta vanha hyvä keino on try-catch –lohkojen käyttö. KYAMK/J.Ansamäki/Olio-ohjelmointi
Esimerkkikoodi • #include <iostream.h> • void main(){ • int tulos, luku=4, jakaja=0; • try{ • if (jakaja==0) • throw(jakaja); • tulos=luku/jakaja; • cout<<"Tulos on: "<<tulos<<endl; • } • catch(int jakaja){ • cout<<"\nJakaja ei voi olla: "<<jakaja; • cout<<"Anna uusi jakaja: "; • cin>>jakaja; • if(jakaja==0) • throw; • cout<<"\nJakaja OK!\n"; • } • } KYAMK/J.Ansamäki/Olio-ohjelmointi
Esimerkin läpikäyntiä • Koodin ’vaarallinen’ osuus on sijoitettu try-lohkoon. • Jos virhetilanne huomataan ’heitetään’ poikkeus throw-komennolla. Tässä tapauksessa poikkeus on siis int-tyyppinen tieto: jakaja. • catch-lohko ’sieppaa’ poikkeuksen, mikäli käsittelijä on samaa tyyppiä kuin heitetty poikkeus. • throw ilman parametria aiheuttaa ohjelman keskeyttämisen. KYAMK/J.Ansamäki/Olio-ohjelmointi
Tehtävä 25 • Muuta esimerkkikoodia siten, että ohjelman toiminta on järkevää. • Jakaja kysytään alussakin käyttäjältä. • Virhekäsittelystä palataan koittamaan jakamista uudella jakajalla. • Tutustu tarvittaessa Visual Studion ohjeistukseen. • Lisää poikkeustenkäsittelyä omaan harjoitustyöhösi. KYAMK/J.Ansamäki/Olio-ohjelmointi
Debuggaus • Käännettäessä valittavissa kaksi eri tilaa: Debug ja Release. • Debuggausvalintoja ja –tiloja voi valita Project Settings –valintaikkunan C/C++ välilehdeltä. • Debug-työkalurivi. KYAMK/J.Ansamäki/Olio-ohjelmointi
Windows-ohjelmointi • Windows-ohjelmointi Visual C++:lla koostuu erilaisista vaiheista: • Käyttöliittymän rakentaminen. • Ohjelmakoodin tuottaminen. • Ohjelmakoodin liittäminen käyttöliittymään. • MDI/SDI/Dialogipohjainen/… • Kevyenä harjoituksena teemme johdetusti seuraavaksi pienen dialogipohjaisen sovelluksen. KYAMK/J.Ansamäki/Olio-ohjelmointi
Nappi-sovellus • Projektin tyypin valitseminen • MFC AppWizard(exe), Nappi, dialogi • Testiajo • Dialogipohjan muuttaminen • ResourceView, Dialog, IDD_NAPPI_DIALOG • TODO-teksti pois, painamua-nappi tilalle • Ohjelmakoodin liittäminen nappiin • Oikea hiiren nappi nappulan päällä -> Events • BN_CLICKED, Add/Edit • MessageBox(”Kiitti, jo helpotti!”); • Tutki luotuja tiedostoja KYAMK/J.Ansamäki/Olio-ohjelmointi
Muuta • Aiheita, joita käsitellään, mikäli jää aikaa ja mielenkiintoa riittää: • templatet • Katsaus funktiokirjastoihin • Operaattoreiden ylikuormitus • Muodostimet ja tuhoajat perinnässä • Ketjutetut listat… • ? KYAMK/J.Ansamäki/Olio-ohjelmointi