Poikkeuskäsittely- lohkot tMyn1 Poikkeuskäsittelylohkot try-catch Poikkeustilanteiden käsittelymekanismi toteutetaan varatuilla sanoilla try, throw ja.

Slides:



Advertisements
Samankaltaiset esitykset
Tuloksellinen Java-ohjelmointi Luku 3 Luokkien käyttäminen
Advertisements

Rajapintaluokat Rajapintaluokka luettelee metodit, joille tulee löytyä toteutus asianomaisen rajapinnan toteuttavista luokista. Rajapintaluokka on siis.
@ Leena Lahtinen Helia Ohjelman perusrakenteet 1. PERÄKKÄISRAKENNE 2. VALINTARAKENNE 3. TOISTORAKENNE.
Minimaalinen Java-ohjelma •Kaikki ohjelmakoodi on luokkamäärityksen sisällä •Ohjelma käynnistyy ”public static void main(String[] args)”-metodista •System.out.print()
Olio-ohjelmoinnin perusteet luento 3: Muuttujista ja funktioista Sami Jantunen LTY/Tietotekniikan osasto.
© Jukka Harju, Viittausmuuttujat. © Jukka Harju, Viittaukset •Viittausmuuttuja sisältää tiedon siitä missä muistipaikassa olio.
JavaScript (c) Irja & Reino Aarinen, 2007
Luokkien väliset koostesuhteet
Luokan otsikko- ja toteutustiedosto tMyn1 Luokan otsikko- ja toteutustiedosto •Tähän asti ohjelmaesimerkit on toteutettu siten, että kaikki koodi on yhdessä.
Ohjelman perusrakenteet
Julkaisukielet ja - tekniikat tMyn1 Julkaisukielet ja -tekniikat •Verkko-ohjelmointi voidaan jakaa kahteen osaan: asiakaspuolen ja palvelinpuolen ohjelmointiin.
Jukka Juslin Poikkeukset ja niiden paikallistaminen * Jukka Juslin * Liittyy oppikirjan lukuun 11.
Johdetun luokan määrittely tMyn1 Johdetun luokan määrittely •Kun johdettu luokka periytetään kantaluokasta, saadaan kantaluokan jäsenet enemmän tai vähemmän.
OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT. LUOKKA JAVA ohjelma koostuu luokista LUOKKA sisältää metodeja molemmat sisältävät attribuutteja eli muuttujia.
@ Leena Lahtinen OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT.
Ohjelman jakaminen useampaan tiedostoon Olio-ohjelmointi (C++) KYAMK, Jarkko Ansamäki 2001.
Olio-ohjelmoinnin perusteet luento 3
OLIO-OHJELMOINTI PERUSTEET PERUSTIETOTYYPIT
Vakio-osoitin ja osoitin vakioon tMyn1 Vakio-osoitin ja osoitin vakioon Tavallinen osoitin voi vaihtaa osoitettavaa keskusmuistialuetta. Tämä voidaan tehdä.
© Jukka Harju, Jukka Juslin Java-ohjelmointi Opas ammattimaiseen osaamiseen Luku 9 Poikkeuskäsittely.
Poikkeustenkäsittely  Mitä poikkeustenkäsittely tarkoittaa?  Poikkeuksen käsitteleminen  Poikkeusluokkien hierarkia  Poikkeuksen heittäminen 1.
Ohjelman perusrakenteet
Osoitin ja char- tietotyyppi tMyn1 Osoitin ja char-tietotyyppi Osoitinmuuttuja, joka on tyyppiä char* voidaan alustaa merkkijonolla: char* alku=”En toivo.
Sami Jantunen LTY/Tietotekniikan osasto
Dynaamiset oliottMyn1 Dynaamiset oliot Dynaamisen olion tunnuksen esittely ja olion määrittely voivat tapahtua yhtäaikaisesti tai eri aikaan. Dynaamisen.
Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan.
Virtuaaliset jäsenfunktiot tMyn1 Virtuaaliset jäsenfunktiot Virtuaalinen jäsenfunktio on esiteltävä monimuotoisessa kantaluokassa. Virtuaalisen jäsenfunktion.
© Jukka Harju, Jukka Juslin
Tekstitiedostosta lukeminen tMyn1 Tekstitiedostosta lukeminen Tiedosto voidaan avata pelkästään lukemista varten tai kirjoittamista ja lukemista varten.
Funktion esittely eli prototyyppi tMyn1 Funktion esittely eli prototyyppi Funktion esittely (function declaration) kertoo funktion nimen, parametrien tyypit.
Johdetun luokan olion alustus tMyn1 Johdetun luokan olion alustus määrätyillä arvoilla Kun ohjelmassa esiintyy johdetun luokan olion määrittely, järjestelmä.
Luokan muodostintMyn1 Luokan muodostin Olioihin kohdistuvia automaattisia toimintoja ovat luonti, alustus, kopiointi, sijoitus, tyhjennys ja tuhoaminen.
7. Oliot ja viitteet.
Luokan määrittely class-määreellä tMyn1 Luokan määrittely class-määreellä Luokan määrittely tarkoittaa luokan tietojäsenten esittelyä ja jäsenfunktioiden.
Lueteltu tyyppitMyn1 Lueteltu tyyppi Lueteltu tyyppi on tietotyyppi, jonka arvot luetellaan erikseen tyypin määrittelyn yhteydessä. Lueteltua tietotyyppiä.
Kuinka niitä käsitellään
4. Attribuutit 4.1. Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2.
@ Leena Lahtinen OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT.
Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan.
Ohjelman keskeytys virhetilanteessa tMyn1 Ohjelman keskeytys virhetilanteessa Poikkeustilanteet voidaan ryhmitellä logiikkavirheisiin ja muihin ajonaikaisiin.
Poikkeukset Yleistä Virheeseen varautuminen tarkoittaa sitä, että ohjelmoija huomioi koodia kirjoittaessaan ajonaikaisen virheen mahdollisuuden.
Johdetun luokan olion alustus tMyn1 Johdetun luokan olion alustus määrätyillä arvoilla Kun ohjelmassa esiintyy johdetun luokan olion määrittely, järjestelmä.
Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Poikkeukset ja tietovirrat: Virhetilanteiden ja syötevirtojen käsittely.
Johdetun luokan olion esittely... tMyn1 Johdetun luokan olion esittely ja määrittely Esittelyluokka tarkoittaa olion tunnuksen luokkaa. Määrittelyluokka.
Poikkeustenkäsittely- lohkot tMyn1 Poikkeustenkäsittelylohkot try-catch Poikkeustilanteiden käsittelymekanismi toteutetaan varatuilla sanoilla try, throw.
Tiedostojen käsittely
Oman poikkeus- käsittelyfunktion tMyn1 Oman poikkeuskäsittelyfunktion määrittely Funktion tulisi muodostaa ainoastaan sellaisia poikkeuksia, jotka on sallittu.
Tekstitiedostoon kirjoittaminen tMyn1 Tekstitiedostoon kirjoittaminen Tiedostoja käsitellään ohjelmassa tiedosto-olion avulla. Tiedosto-olion luokka sisältää.
Kontrollirakenteet laajemmin
Ohjelmointi työtä n. 16 h/vko onnistumista työtä n. 16 h/vko onnistumista #include int main(void) { std::cout
Monimuotoinen luokka tMyn1 Monimuotoinen luokka Monimuotoinen luokka mahdollistaa saman jäsenfunktion toteutuksen monella tavalla. Tällöin puhutaan virtuaalisesta.
Tiedon vieminen funktiolle tMyn1 Tiedon vieminen funktiolle, parametrit Argumentin vieminen funktiolle voidaan toteuttaa kahdella menetelmällä: –Pass-by-Value.
Johdetun luokan olion alustus tMyn1 Johdetun luokan olion alustus määrätyillä arvoilla Kun ohjelmassa esiintyy johdetun luokan olion määrittely, järjestelmä.
Kantaluokan määrittely tMyn1 Kantaluokan määrittely Perinnän käyttöön liittyvät varatut sanat private, protected, public, final ja abstract. Ne tarkoittavat.
Javan oliovirrat eli oliotiedostojen käsittely. Olio- eli objektitiedostojen käsittely Käsittely täysin samanlaista kuin muiden tiedostojen 1.Otetaan.
Johdetun luokan määrittely tMyn1 Johdetun luokan määrittely Kun johdettu luokka periytetään kantaluokasta, saadaan kantaluokan jäsenet enemmän tai vähemmän.
1 © Jukka Juslin Luokat, attribuutit ja metodit Yleistietoa: seuraavalla koulutusviikolla tarkempi käsittely.
14. Poikkeukset Sisällys Johdanto poikkeuksiin. Poikkeusten käsittely: − Poikkeusten käsittely paikallisesti. − Poikkeusten heittäminen. Exception.
Osoittimen määrittely ja alustus tMyn1 Osoittimen määrittely ja alustus Osoitin (pointer) on muuttuja, joka voi sisältää keskusmuistiosoitteen. Osoitinmuuttujan.
Valintarakenne valintarakenne alkaa aina kysymyksellä eli ehdolla ehto tarkoittaa, että muuttujan sisältöä verrataan toisen muuttujan sisältöön tai vakioon.
Tiedostot. 8.2 Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen.
6. Tiedostot.
Poikkeustenkäsittelylohkot try-catch
14. Poikkeukset.
Kuinka niitä käsitellään
Kuinka niitä käsitellään
14. Hyvä ohjelmointitapa.
14. Poikkeukset.
Ohjelman perusrakenteet
14. Poikkeukset.
Esityksen transkriptio:

Poikkeuskäsittely- lohkot tMyn1 Poikkeuskäsittelylohkot try-catch Poikkeustilanteiden käsittelymekanismi toteutetaan varatuilla sanoilla try, throw ja catch. try aloittaa poikkeuskäsittelylohkon, johon ohjelmoija kirjoittaa virhealttiin ohjelmakoodin. Jos try-lohkossa tapahtuu virhe, throw luo poikkeuksen, jonka catch-lohko käsittelee. catch-lohko sisältää kullekin virhetilanteelle käsittelijän. try- ja catch-lohkot sijaitsevat suoritusjärjestyksessä peräkkäin.

Poikkeuskäsittely- lohkot tMyn2 Poikkeus voi olla mitä tahansa tyyppiä oleva tieto tai olio. Usein on hyödyllistä määritellä poikkeuksen käsittelyä varten erillinen luokka, johon voidaan määritellä tietojäseniä virhetilanteiden tallettamista varten. Kun poikkeustilanne syntyy, ohjelman eteneminen keskeytyy, ja ohjelma etsii sopivaa poikkeuksenkäsittelijää.

Poikkeuskäsittely- lohkot tMyn3 try-catch -lohkot: try { //virhealtis toiminta } catch (tyyppi poikkeus) { //poikkeuskäsittely } catch(...) { //poikkeuskäsittely }

Poikkeuskäsittely- lohkot tMyn4 try- ja catch -lohkot sijaitsevat suoritusjärjestyksessä peräkkäin. try-lohko sisältää ohjelmakoodin, joka voi aiheuttaa poikkeustilanteen. catch-lohkossa voidaan määritellä poikkeuskäsittelijä kullekin eri poikkeukselle. Poikkeuskäsittelijä on catch-lohkossa sijaitseva ohjelmakoodi. Poikkeustieto tai olio määritellään catch-sanan jäljessä olevien sulkeiden välissä.

Poikkeuskäsittely- lohkot tMyn5 tyyppi tarkoittaa poikkeustiedon tai olion tyyppiä ja poikkeus on tieto tai olio, johon voidaan viitata catch- lohkossa. Poikkeus on paikallinen lohkossa. Jos sulkeiden sisällä on kolme pistettä, käsittelee lohko minkä tahansa poikkeustilanteen. Poikkeuskäsittelylohkot voivat olla myös sisäkkäisiä, joten ne voivat muodostaa sisäkkäisiä tasoja.

Poikkeuskäsittely- lohkot tMyn6 Poikkeustilanteen aiheuttaminen varatulla sanalla throw: throw (poikkeukset); throw; Poikkeukset määritellään throw-sanan jäljessä. Poikkeukset voivat olla sulkeiden sisällä. Jos tilanteesta syntyy useita poikkeuksia, on poikkeukset eroteltava pilkulla toisistaan. throw-sanaa käytetään normaalisti try-lohkossa. catch-lohkossa on kuitenkin mahdollista nostattaa uusi poikkeustilanne.

Poikkeuskäsittely- lohkot tMyn7 Tällöin voidaan throw-sanaa käyttää ilman erityistä poikkeustietoa, jolloin poikkeuskäsittely siirretään seuraavaksi korkeammalle poikkeuskäsittelytasolle sisäkkäisissä poikkeuskäsittelyrakenteissa. Jos throw esiintyy uloimmalla tasolla, ohjelma kutsuu terminate-funktiota. Kokeillaan try-catch –rakenteen toimintaa. Jos catch- lohkossa ei ole tarvetta käyttää mitään sellaista tietoa joka pitäisi tuoda throw-tapahtuman mukana, niin silloin catch-sanan jälkeisiin sulkuihin riittää pelkkä tieto siitä, minkä tyypin poikkeus siinä lohkossa käsitellään:

Poikkeuskäsittely- lohkot tMyn8 #include "stdafx.h" #include using namespace System; using namespace std; int main(array ^args) { double osamaara=0, jaettava=0, jakaja=0; cout<<"Anna jaettava ja jakaja, whitespace v\204liin! "; while(cin>>jaettava>>jakaja) { try { if(jakaja==0)

Poikkeuskäsittely- lohkot tMyn9 throw(jakaja); osamaara=jaettava/jakaja; cout<<"Osam\204\204r\204ksi saatiin " <<osamaara<<"."<<endl; } catch(double) cout<<"Jakaja ei saa olla sit\204 sun t\204t\204!” <<endl; cout<<"Anna jaettava ja jakaja, whitespace v\204liin!\n" <<"Jos haluat lopettaa, anna jokin kirjain: "; } return 0; } Pelkkä tieto poikkeuksen tyypistä riittää!

Poikkeuskäsittely- lohkot tMyn10 Monipuolistetaan edellistä esimerkkiä lisäämällä catch-sanan jälkeisiin sulkuihin tyypin lisäksi se tieto, joka saatiin throw-tapahtumasta:

Poikkeuskäsittely- lohkot tMyn11 #include "stdafx.h" #include using namespace System; using namespace std; int main(array ^args) { double osamaara=0, jaettava=0, jakaja=0; string viesti; cout<<"Anna jaettava ja jakaja, whitespace v\204liin! "; while(cin>>jaettava>>jakaja)

Poikkeuskäsittely- lohkot tMyn12 { try { if(jakaja==0) throw(jakaja); if(jaettava>99999) { viesti="Ei noin isoja lukuja, please!!"; throw viesti; } osamaara=jaettava/jakaja; cout<<"Osam\204\204r\204ksi saatiin " <<osamaara<<"."<<endl; }

Poikkeuskäsittely- lohkot tMyn13 catch(double jakaja) { cout<<"Jakaja ei saa olla: " <<jakaja<<"!"<<endl; } catch (string tiedote) { cout<<tiedote<<endl; } cout<<"Anna jaettava ja jakaja, whitespace v\204liin!\n" <<"Jos haluat lopettaa, anna jokin kirjain: "; } return 0; }

Poikkeuskäsittely- lohkot tMyn14

Poikkeuskäsittely- lohkot tMyn15 Ohjelmoija voi määritellä erilaisiin poikkeustilanteisiin liittyviä poikkeusluokkia. Poikkeusluokkaan luodaan poikkeusolio poikkeustilanteen syntyessä throw-sanalla. Poikkeusluokan ja –olion käyttö vastaa tavallisen luokan ja sen olion käyttöä. Yksi luonnollisimmista luokkarakenteista tässä tilanteessa lienee sisäkkäiset luokat (nested classes). Rakenne on sellainen, että toteutettavaan luokkaan sisällytetään tuon kyseisen luokan poikkeusluokka. Aletaan rakentamaan tällaista sisäkkäistä luokkarakennetta ”ihan alusta”.

Poikkeuskäsittely- lohkot tMyn16 Olkoot luokkana suorakaide, ja luokan tietojäseninä ovat suorakaiteen leveys ja korkeus. Tässä lähtöversiossa ei ole toteutettuna mitään poikkeusluokkaa, vaan ohjelma keskeytetään, jos leveydeksi tai korkeudeksi annetaan negatiivinen arvo:

Poikkeuskäsittely- lohkot tMyn17 // Suorakaide.h #ifndef SUORAKAIDE_H #define SUORAKAIDE_H class Suorakaide { public: Suorakaide(); void AsetaLeveys(); void AsetaKorkeus(); void LaskeAla(); private: double m_leveys; double m_korkeus; }; #endif

Poikkeuskäsittely- lohkot tMyn18 // Suorakaide.cpp #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; Suorakaide::Suorakaide() { cout<<"Oletusmuodostin, olio "<<this<<endl; AsetaLeveys(); AsetaKorkeus(); }

Poikkeuskäsittely- lohkot tMyn19 void Suorakaide::AsetaLeveys() { double leveys; cout<<"Anna leveys: "; cin>>leveys; cin.get(); if(leveys>=0) m_leveys=leveys; else { cout<<"Annoit virheellisen leveyden!"<<endl; exit(EXIT_FAILURE); }

Poikkeuskäsittely- lohkot tMyn20 void Suorakaide::AsetaKorkeus() { double korkeus; cout<<"Anna korkeus: "; cin>>korkeus; cin.get(); if(korkeus>=0) m_korkeus=korkeus; else { cout<<"Annoit virheellisen korkeuden!"<<endl; exit(EXIT_FAILURE); } void Suorakaide::LaskeAla() { cout<<"Pinta-ala on "<<m_leveys*m_korkeus <<" pa-yksikk\224\204."<<endl; }

Poikkeuskäsittely- lohkot tMyn21 // poikkeusSuorak1Main.cpp : main project file. #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; int main(array ^args) { Suorakaide eka=Suorakaide(); eka.LaskeAla(); return 0; }

Poikkeuskäsittely- lohkot tMyn22

Poikkeuskäsittely- lohkot tMyn23 Muutetaan jäsenfunktioita AsetaLeveys() ja AsetaKorkeus() siten, että ohjelmasta tulee käyttäjäystävällisempi – siis ”pakotetaan” käyttäjä antamaan tolkulliset arvot. Muutoin ratkaisu on sama kuin edellä:

Poikkeuskäsittely- lohkot tMyn24 // Suorakaide.h #ifndef SUORAKAIDE_H #define SUORAKAIDE_H class Suorakaide { public: Suorakaide(); void AsetaLeveys(); void AsetaKorkeus(); void LaskeAla(); private: double m_leveys; double m_korkeus; }; #endif

Poikkeuskäsittely- lohkot tMyn25 // Suorakaide.cpp #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; Suorakaide::Suorakaide() { cout<<"Oletusmuodostin kutsuttu, olio "<<this<<endl; AsetaLeveys(); AsetaKorkeus(); }

Poikkeuskäsittely- lohkot tMyn26 void Suorakaide::AsetaLeveys() { bool koetasUudelleen=true; while(koetasUudelleen) { double leveys; cout<<"Anna leveys: "; cin>>leveys; cin.get(); if(leveys>=0) { m_leveys=leveys; koetasUudelleen=false; } else { cout<<"Annoit virheellisen leveyden!"<<endl; koetasUudelleen=true; }

Poikkeuskäsittely- lohkot tMyn27 void Suorakaide::AsetaKorkeus() { bool koetasUudelleen=true; while(koetasUudelleen) { double korkeus; cout<<"Anna korkeus: "; cin>>korkeus; cin.get(); if(korkeus>=0) { m_korkeus=korkeus; koetasUudelleen=false; } else { cout<<"Annoit virheellisen korkeuden!"<<endl; koetasUudelleen=true; }

Poikkeuskäsittely- lohkot tMyn28 void Suorakaide::LaskeAla() { cout<<"Pinta-ala on "<<m_leveys*m_korkeus <<" pa-yksikk\224\204."<<endl; }

Poikkeuskäsittely- lohkot tMyn29 // poikkeusSuorak2Main.cpp : main project file. #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; int main(array ^args) { Suorakaide eka=Suorakaide(); eka.LaskeAla(); return 0; }

Poikkeuskäsittely- lohkot tMyn30

Poikkeuskäsittely- lohkot tMyn31 Lisätään luokkaan Suorakaide jäsenfunktioksi poikkeusluokka ilman ensimmäistäkään tietojäsentä tai jäsenfunktiota. Annetaan siis järjestelmän generoida tarvittaessa poikkeusluokan oletusmuodostin. Poikkeusluokkaan luodaan poikkeusolio poikkeustilanteen syntyessä throw-sanalla. Tässä riittää, että catch-sanan jälkeisiin sulkeisiin liitetään tieto pelkästään poikkeuksen aiheuttaneen olion tyypistä (vrt. ensimmäinen esimerkki!)

Poikkeuskäsittely- lohkot tMyn32 // Suorakaide.h #ifndef SUORAKAIDE_H #define SUORAKAIDE_H class Suorakaide { public: //Poikkeusluokka class negatiivinenArvo {}; Suorakaide(); void AsetaLeveys(); void AsetaKorkeus(); void LaskeAla(); private: double m_leveys; double m_korkeus; }; #endif

Poikkeuskäsittely- lohkot tMyn33 // Suorakaide.cpp #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; Suorakaide::Suorakaide() { cout<<"Oletusmuodostin, olio "<<this<<endl; AsetaLeveys(); AsetaKorkeus(); }

Poikkeuskäsittely- lohkot tMyn34 void Suorakaide::AsetaLeveys() { double leveys; cout<<"Anna leveys: "; cin>>leveys; cin.get(); if(leveys>=0) m_leveys=leveys; else throw negatiivinenArvo(); } Kutsutaan poikkeusluokan oletusmuodostinta nimellä, vaikka se siis on kääntäjän generoima.

Poikkeuskäsittely- lohkot tMyn35 void Suorakaide::AsetaKorkeus() { double korkeus; cout<<"Anna korkeus: "; cin>>korkeus; cin.get(); if(korkeus>=0) m_korkeus=korkeus; else throw negatiivinenArvo(); } void Suorakaide::LaskeAla() { cout<<"Pinta-ala on "<<m_leveys*m_korkeus <<" pa-yksikk\224\204."<<endl; }

Poikkeuskäsittely- lohkot tMyn36 // poikkeusSuorak3Main.cpp : main project file. #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; int main(array ^args) { try { Suorakaide eka=Suorakaide(); eka.LaskeAla(); } catch (Suorakaide::negatiivinenArvo) { cout<<"Annoit negatiivisen luvun."<<endl; } return 0; } Pelkkä tyyppitieto riittää.

Poikkeuskäsittely- lohkot tMyn37

Poikkeuskäsittely- lohkot tMyn38 Edellinen esimerkki voitaisiin muuttaa siten, että toteutettaisiin itse oletusmuodostin (joka ei tässä vaiheessa kylläkään tekisi mitään). Ohjelman toiminta pysyisi siis muuttumattomana. Kokeillaan sitä:

Poikkeuskäsittely- lohkot tMyn39 // Suorakaide.h #ifndef SUORAKAIDE_H #define SUORAKAIDE_H class Suorakaide { public: class negatiivinenArvo { public: negatiivinenArvo(); }; Suorakaide(); void AsetaLeveys(); void AsetaKorkeus(); void LaskeAla(); private: double m_leveys; double m_korkeus; }; #endif

Poikkeuskäsittely- lohkot tMyn40 // Suorakaide.cpp #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; Suorakaide::negatiivinenArvo::negatiivinenArvo() { cout<<"Poikkeusluokan muodostin, olio "<<this<<endl; } Suorakaide::Suorakaide() { cout<<"Suorakaide-luokan oletusmuodostin, olio "<<this<<endl; AsetaLeveys(); AsetaKorkeus(); }

Poikkeuskäsittely- lohkot tMyn41 void Suorakaide::AsetaLeveys() { double leveys; cout<<"Anna leveys: "; cin>>leveys; cin.get(); if(leveys>=0) m_leveys=leveys; else throw negatiivinenArvo(); }

Poikkeuskäsittely- lohkot tMyn42 void Suorakaide::AsetaKorkeus() { double korkeus; cout<<"Anna korkeus: "; cin>>korkeus; cin.get(); if(korkeus>=0) m_korkeus=korkeus; else throw negatiivinenArvo(); } void Suorakaide::LaskeAla() { cout<<"Pinta-ala on "<<m_leveys*m_korkeus <<" pa-yksikk\224\204."<<endl; }

Poikkeuskäsittely- lohkot tMyn43 // poikkeusSuorak3aMain.cpp : main project file. #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; int main(array ^args) { try { Suorakaide eka=Suorakaide(); eka.LaskeAla(); } catch (Suorakaide::negatiivinenArvo) { cout<<"Annoit negatiivisen luvun."<<endl; } return 0; }

Poikkeuskäsittely- lohkot tMyn44

Poikkeuskäsittely- lohkot tMyn45 Monipuolistetaan ohjelman toimintaa siten, että toteutetaan poikkeusluokat erikseen leveydelle ja korkeudelle. Lisäksi ”pakotetaan” jälleen ohjelman käyttäjä antamaan kelvolliset arvot:

Poikkeuskäsittely- lohkot tMyn46 // Suorakaide.h #ifndef SUORAKAIDE_H #define SUORAKAIDE_H class Suorakaide { public: class negatiivinenLeveys { public: negatiivinenLeveys(); }; class negatiivinenKorkeus { public: negatiivinenKorkeus(); };

Poikkeuskäsittely- lohkot tMyn47 Suorakaide(); void AsetaLeveys(); void AsetaKorkeus(); void LaskeAla(); private: double m_leveys; double m_korkeus; }; #endif

Poikkeuskäsittely- lohkot tMyn48 // Suorakaide.cpp #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; Suorakaide::Suorakaide() { cout<<"Suorakaide-luokan oletusmuodostin, olio "<<this<<endl; m_leveys=0; m_korkeus=0; }

Poikkeuskäsittely- lohkot tMyn49 void Suorakaide::AsetaLeveys() { double leveys; cout<<"Anna leveys: "; cin>>leveys; cin.get(); if(leveys>=0) m_leveys=leveys; else throw negatiivinenLeveys(); }

Poikkeuskäsittely- lohkot tMyn50 void Suorakaide::AsetaKorkeus() { double korkeus; cout<<"Anna korkeus: "; cin>>korkeus; cin.get(); if(korkeus>=0) m_korkeus=korkeus; else throw negatiivinenKorkeus(); } Suorakaide::negatiivinenLeveys::negatiivinenLeveys() { cout<<"negatiivinenLeveys-luokan poikkeus, olio "<<this<<endl; }

Poikkeuskäsittely- lohkot tMyn51 Suorakaide::negatiivinenKorkeus::negatiivinenKorkeus() { cout<<"negatiivinenKorkeus-luokan poikkeus, olio "<<this<<endl; } void Suorakaide::LaskeAla() { cout<<"Pinta-ala on "<<m_leveys*m_korkeus <<" pa-yksikk\224\204."<<endl; }

Poikkeuskäsittely- lohkot tMyn52 // poikkeusSuorak4Main.cpp : main project file. #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; int main(array ^args) { Suorakaide eka=Suorakaide(); bool koetasUudelleen=true;

Poikkeuskäsittely- lohkot tMyn53 while(koetasUudelleen) { try { eka.AsetaLeveys(); koetasUudelleen=false; } catch (Suorakaide::negatiivinenLeveys) { cout<<"Annoit negatiivisen luvun " <<"suorakaiteen leveydeksi."<<endl; } koetasUudelleen=true;

Poikkeuskäsittely- lohkot tMyn54 while(koetasUudelleen) { try { eka.AsetaKorkeus(); koetasUudelleen=false; } catch (Suorakaide::negatiivinenKorkeus) { cout<<"Annoit negatiivisen luvun " <<"suorakaiteen korkeudeksi."<<endl; } eka.LaskeAla(); return 0; }

Poikkeuskäsittely- lohkot tMyn55

Poikkeuskäsittely- lohkot tMyn56 Tarkennetaan edellistä esimerkkiohjelmaa siten, että annetaan ohjelman käyttäjälle tieto siitä mitä tuli annettua – jos tuli annettua virheellinen arvo. Tämä edellyttää poikkeusluokkien uudelleenkirjoittamista:

Poikkeuskäsittely- lohkot tMyn57 // Suorakaide.h #ifndef SUORAKAIDE_H #define SUORAKAIDE_H class Suorakaide { public: class negatiivinenLeveys { public: negatiivinenLeveys(double); double HaeArvo(); private: double m_arvo; };

Poikkeuskäsittely- lohkot tMyn58 class negatiivinenKorkeus { public: negatiivinenKorkeus(double); double HaeArvo(); private: double m_arvo; }; Suorakaide(); void AsetaLeveys(); void AsetaKorkeus(); void LaskeAla(); private: double m_leveys; double m_korkeus; }; #endif

Poikkeuskäsittely- lohkot tMyn59 // Suorakaide.cpp #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; Suorakaide::negatiivinenLeveys::negatiivinenLeveys(double leveys) { cout<<"negatiivinenLeveys-luokan poikkeus, olio "<<this<<endl; m_arvo=leveys; } double Suorakaide::negatiivinenLeveys::HaeArvo() { return m_arvo; }

Poikkeuskäsittely- lohkot tMyn60 Suorakaide::negatiivinenKorkeus::negatiivinenKorkeus(double korkeus) { cout<<"negatiivinenKorkeus-luokan poikkeus, olio "<<this<<endl; m_arvo=korkeus; } double Suorakaide::negatiivinenKorkeus::HaeArvo() { return m_arvo; } Suorakaide::Suorakaide() { cout<<"Suorakaide-luokan oletusmuodostin, olio "<<this<<endl; m_leveys=0; m_korkeus=0; }

Poikkeuskäsittely- lohkot tMyn61 void Suorakaide::AsetaLeveys() { double leveys; cout<<"Anna leveys: "; cin>>leveys; cin.get(); if(leveys>=0) m_leveys=leveys; else throw negatiivinenLeveys(leveys); }

Poikkeuskäsittely- lohkot tMyn62 void Suorakaide::AsetaKorkeus() { double korkeus; cout<<"Anna korkeus: "; cin>>korkeus; cin.get(); if(korkeus>=0) m_korkeus=korkeus; else throw negatiivinenKorkeus(korkeus); } void Suorakaide::LaskeAla() { cout<<"Pinta-ala on "<<m_leveys*m_korkeus <<" pa-yksikk\224\204."<<endl; }

Poikkeuskäsittely- lohkot tMyn63 // poikkeusSuorak5Main.cpp : main project file. #include "stdafx.h" #include #include "Suorakaide.h" using namespace System; using namespace std; int main(array ^args) { Suorakaide eka=Suorakaide(); bool koetasUudelleen=true;

Poikkeuskäsittely- lohkot tMyn64 while(koetasUudelleen) { try { eka.AsetaLeveys(); koetasUudelleen=false; } catch (Suorakaide::negatiivinenLeveys leveys) { cout<<"Annoit arvon "<<leveys.HaeArvo() <<" suorakaiteen leveydelle."<<endl; } koetasUudelleen=true;

Poikkeuskäsittely- lohkot tMyn65 while(koetasUudelleen) { try { eka.AsetaKorkeus(); koetasUudelleen=false; } catch (Suorakaide::negatiivinenKorkeus korkeus) { cout<<"Annoit arvon "<<korkeus.HaeArvo() <<" suorakaiteen korkeudelle."<<endl; } eka.LaskeAla(); return 0; }

Poikkeuskäsittely- lohkot tMyn66

Poikkeuskäsittely- lohkot tMyn67 Myös UML tunnistaa sisäkkäiset luokat. Viimeisimmän esimerkkiohjelman luokkakaavio voisi näyttää seuraavan tyyliseltä, kuva 1:

Poikkeuskäsittely- lohkot tMyn68 Suorakaide - m_leveys: double - m_korkeus: double + Suorakaide() + AsetaLeveys(): void + AsetaKorkeus(): void + LaskeAla(): void negatiivinenKorkeus - m_arvo: double + negatiivinenKorkeus (korkeus: double) + HaeArvo(): double negatiivinenLeveys - m_arvo: double + negatiivinenLeveys (leveys: double) + HaeArvo(): double Kuva 1. UML-kaavio sisäkkäisistä luokista.