Virtuaalifunktiot ja polymorfismi

Koko: px
Aloita esitys sivulta:

Download "Virtuaalifunktiot ja polymorfismi"

Transkriptio

1 Virtuaalifunktiot ja polymorfismi 16 Virtuaalifunktiot ja polymorfismi Polymorfismi on niin tehokas olio-ohjelmoinnin ominaisuus, että tulet varmastikin käyttämään sitä lähes kaikissa C++-ohjelmissasi. Polymorfismi vaatii periytettyjä luokkia, ja tämän luvun sisältö nojaa vahvasti edellisessä luvussa käsiteltyihin periytymisen perusteisiin. Tämän luvun aiheita ovat: Mikä polymorfismi on ja miten luokat saadaan hyödyntämään polymorfismia Mikä on virtuaalifunktio Milloin ja miksi luokkahierarkiassa tarvitaan virtuaalisia tuhoajafunktioita Miten virtuaalifunktioiden oletusparametrejä käytetään Mikä on aito virtuaalifunktio ja miten funktio määritellään sellaiseksi Mikä on abstrakti luokka Miten luokan tyyppejä voidaan muuntaa luokkahierarkiassa Miten olioon osoittavan osoittimen tyyppi saadaan selville suoritusaikana Mitä ovat osoittimet jäseniin ja miten niitä käytetään Polymorfismin perusteet Kuten tulemme huomaamaan, polymorfismiin kuuluu aina olioon osoittavan osoittimen tai viittauksen käyttö kutsuttaessa funktiota. Lisäksi polymorfismi toimii ainoastaan luokkahierarkiassa, joten mahdollisuus periyttää luokka toisesta luokasta on polymorfismin perustana. Mitä polymorfismilla sitten saadaan aikaan? Saamme karkean kuvan sen toiminnasta tutkimalla esimerkkiä, jossa on lisää laatikoita, mutta ensin meidän tulee ymmärtää, mikä merkitys on osoittimella kantaluokkaan. 621

2 C++ Ohjelmoijan käsikirja Osoitin kantaluokkaan Eräs asia, jota käsittelimme edellisessä luvussa, oli se, että periytetyn luokan olio on kantaluokan olioiden alijoukko - toisin sanoen, jokainen periytetty luokka on myös kantaluokka. Eli voit aina käyttää osoitinta kantaluokkaan tallettamaan periytetyn luokan olion osoitteen - voit itse asiassa käyttää jopa osoitinta epäsuoraan kantaluokkaan tähän tarkoitukseen. Alla olevassa kaaviossa PahviLaatikko-luokka on periytetty Laatikko-kantaluokasta ja KauraLtk-luokka on moniperitty Laatikko- ja Sisalto-luokista. Kaavio havainnollistaa, miten osoittimia kantaluokkiin voidaan käyttää periytettyjen olioiden osoitteiden tallettamiseen tällaisessa luokkahierarkiassa. Class Laatikko KauraLtk aamiainen; // Voit tallettaa aammiainen- // olion osoitteen mihin tahansa // kantaosoittimeen: Class PahviLaatikko: public Class Sisalto PahviLaatikko* ppahviltk = &aamiainen; Laatikko* pltk = &aamiainen; Sisalto* psisalto = &aamiainen; Class KauraLtk: public Carton, public Contents Vastakkaiseen suuntaan tämä ei onnistu. Esimerkiksi et voi käyttää KauraLtk*-tyyppistä osoitinta tallettamaan (suoran tai epäsuoran) kantaluokan osoitetta. Tämä on loogista, koska kantaluokka ei kuvaa täydellistä periytetyn luokan oliota. Periytetyn luokan olio sisältää aina jokaisen kantaluokkansa alijoukon, mutta kukin kantaluokka kuvaa vain osaa periytetyn luokan oliosta. Katsotaan esimerkkiä. Oletetaan, että periytämme kaksi luokkaa edellisen luvun mukaisesta Laatikko-luokasta. Tarkoituksenamme on kuvata niillä erilaisia säiliöitä. PahviLaatikkoluokan määrittely on muotoa: class PahviLaatikko: public Laatikko // Luokan yksityiskohdat... Uuden VahvaLtk-luokan määrittely on samantyyppinen: class VahvaLtk: public Laatikko // Luokan yksityiskohdat

3 Virtuaalifunktiot ja polymorfismi Oletetaan nyt, että jokaisen periytetyn tyypin tilavuus lasketaan eri tavalla. Pahvista tehdyn PahviLaatikko-luokan kohdalla tilavuutta täytyy vähentää vain vähän, koska materiaalin paksuus on varsin pieni. VahvaLtk:n kohdalla tilavuutta saattaa tarvita vähentää enemmän, koska kyseessä on vahva ja suojaava rakenne. Edellä olleiden luokkien määrittelyjen pohjalta voimme esitellä ja alustaa osoittimen seuraavasti: PahviLaatikko apahviltk(10.0, 10.0, 5.0); Laatikko* pltk = &apahviltk; Osoitin pltk, joka on tyyppiä osoitin Laatikko-olioon, alustetaan apahviltk:n (joka on tyyppiä PahviLaatikko) osoitteella. Tämä on mahdollista, koska PahviLaatikko on periytetty Laatikkoluokasta ja sisältää täten Laatikko-tyyppisen aliolion. Voimme käyttää samaa osoitinta tallettamaan myös VahvaLtk-olion osoitteen, koska VahvaLtk-luokka on myöskin periytetty Laatikko-luokasta: VahvaLtk kassakaappi(12.0, 8.0, 4.0); pltk = &kassakaappi; Osoitin pltk voi tiettynä hetkenä sisältää minkä tahansa olion osoitteen, jonka kantaluokkana on Laatikko. Osoittimen tyyppi on määrittelyhetkellä staattinen tyyppi - pltk:n staattinen tyyppi on osoitin Laatikko-olioon. Koska pltk on osoitin kantaluokkaan, sillä on myös dynaaminen tyyppi, joka vaihtelee sen mukaan, mihin osoitin osoittaa. Kun pltk osoittaa PahviLaatikkoolioon, sen dynaaminen tyyppi on osoitin PahviLaatikko-luokkaan. Kun pltk osoittaa VahvaLtkolioon, sen dynaaminen tyyppi on osoitin VahvaLtk-luokkaan. Kun pltk osoittaa Laatikkotyyppiseen olioon, sen dynaaminen tyyppi on sama kuin sen staattinen tyyppi. Juuri tässä on polymorfismin taika. Käsittelemme hetken kuluttua ehtoja, joiden voimassa ollessa voit käyttää osoitinta pltk kutsuessasi kantaluokassa tai missä tahansa periytetyissä luokissa määriteltyä funktiota. Funktio valitaan tällöin pltk:n dynaamisen tyypin mukaan. Tarkastellaan seuraavaa lausetta: pltk->tilavuus(); Jos pltk sisältää PahviLaatikko-olion osoitteen, voimme käyttää tätä lausetta kutsuessamme PahviLaatikko-olion tilavuus()-funktiota. Jos pltk osoittaa VahvaLtk-olioon, lause kutsuu VahvaLtk-olion tilavuus()-funktiota. Tämä toimii samalla tavalla muidenkin Laatikko-luokasta periytettyjen luokkien kohdalla. Lause pltk->tilavuus(); voi saada aikaan eri toiminnan, riippuen siitä, mihin pltk osoittaa. Tai mikä tärkeämpää, suoritusaikana valitaan oliolle, johon pltk osoittaa, sopiva toiminta. (Ikään kuin osoittimella olisi sisäänrakennettu switch-lause, joka testaa tyypin ja valitsee kutsuttavan funktion sen mukaan.) Tämä on erittäin tehokas mekanismi. Tulet törmäämään useasti tilanteisiin, joissa käsiteltävänä olevan olion tyyppiä ei voida ratkaista etukäteen - eli tyyppiä ei voida ratkaista suunnitteluhetkellä eikä käännöshetkellä, ainoastaan suoritusaikana. Tällaiset tilanteet voidaan ratkaista helposti polymorfismin avulla. Sitä käytetään runsaasti käyttäjän kanssa vuorovaikutuksessa olevissa ohjelmissa, joissa käyttäjä voi syöttää minkä tahansa tyyppisiä syötteitä. 623

4 C++ Ohjelmoijan käsikirja Esimerkiksi grafiikkasovelluksessa, jossa voidaan piirtää erimuotoisia kuvioita - ympyröitä, viivoja, käyriä jne - voidaan määritellä jokaiselle kuviotyypille oma luokka, joka on periytetty yhteisestä kantaluokasta Kuvio. Ohjelma tallettaa käyttäjän piirtämän kuvion osoitteen kantaluokan osoittimeen pkuvio, joka on tyyppiä osoitin Kuvio-olioon, ja piirtää sopivan kuvion esimerkiksi lauseella pkuvio->piirra();. Tämä kutsuu osoittimen osoittaman kuvion piirra()- funktiota. Eli tämä yksi lause pystyy piirtämään minkä tahansa kuvion. Jotta tämä toimii, on tärkeää, että kutsuttava funktio on kantaluokan jäsen. Katsotaan seuraavaksi tarkemmin perittyjen funktioiden toimintaa. Perittyjen funktioiden kutsuminen Ennen kuin siirrymme tarkemmin polymorfismin saloihin, tulee meidän tarkastella tarkemmin perittyjen funktioiden toimintaa ja miten ne ovat suhteessa sen luokan funktioihin, josta ne on periytetty. Muutamme Laatikko-luokkaa siten, että lisäämme siihen funktion, joka laskee Laatikko-olion tilavuuden sekä toisen funktion, joka tulostaa tilavuuden. Luokkien uudet tiedostot Laatikko.h ja Laatikko.cpp ovat seuraavassa: // Laatikko.h #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko public: Laatikko(double pitarvo = 1.0, double syvarvo = 1.0, double korkarvo = 1.0); // Funktio, joka näyttää olion tilavuuden void naytatilavuus() const; // Funktio, joka laskee Laatikko-olion tilavuuden double tilavuus() const; protected: double pituus; double syvyys; double korkeus; ; #endif // Laatikko.cpp #include <iostream> #include "Laatikko.h" using namespace std; 624 Laatikko::Laatikko(double parvo, double sarvo, double karvo) : pituus(parvo), syvyys(sarvo), korkeus(karvo) void Laatikko::naytaTilavuus() const

5 Virtuaalifunktiot ja polymorfismi cout << "Laatikon käytettävissä oleva tilavuus on " << tilavuus() << endl; double Laatikko::tilavuus() const return pituus * syvyys * korkeus; Emme enää tarvitse käyttäjän määrittelemää tuhoajafunktiota emmekä tulostuslausetta muodostinfunktiossa, joten ne on poistettu. Tällaisen Laatikko-luokan avulla voimme tulostaa Laatikko-olion käytettävissä olevan tilavuuden kutsumalla kyseisen olion naytatilavuus()- funktiota. Käytämme samoja jäsenmuuttujia (pituus, syvyys ja korkeus), jotka on määritelty suojatuiksi, joten niihin ei päästä käsiksi luokasta periytettyjen luokkien jäsenmuuttujista. Määrittelemme myöskin VahvaLtk-luokan, jonka kantaluokkana on Laatikko. VahvaLtk-olion materiaali suojaa laatikon sisältöä, joten sen käytettävissä oleva tilavuus on vain 85% tavallisen Laatikko-olion tilavuudesta. Tästä syystä tarvitsemme toisen version tilavuus()-funktiosta, joka ottaa tämän huomioon: // VahvaLtk.h #ifndef VAHVALTK_H #define VAHVALTK_H #include "Laatikko.h" class VahvaLtk : public Laatikko // Periytetty luokka public: // Muodostinfunktio VahvaLtk(double pituusarvo, double syvyysarvo, double korkeusarvo); ; // Funktio, joka laskee VahvaLtk:n tilavuuden (15% menee laatikolle) double tilavuus() const; #endif // VahvaLtk.cpp #include "VahvaLtk.h" VahvaLtk::VahvaLtk(double parv, double sarv, double karv) : Laatikko(pArv,sArv,kArv) double VahvaLtk::tilavuus() const return 0.85 * pituus * syvyys * korkeus; Periytetyssä luokassa olisi tietysti voinut olla muitakin jäseniä, mutta haluamme pitää sen nyt yksinkertaisena, keskittyen vain perittyjen funktioiden toimintaan. Periytetyn luokan muodostinfunktio kutsuu alkuarvolistassaan yksinkertaisesti kantaluokan muodostinfunktiota, joka asettaa jäsenmuuttujien arvot. Periytetyn luokan muodostinfunktiossa ei tarvita yhtään lausetta. Määrittelemme myöskin uuden version tilavuus()-funktiosta, joka korvaa kantaluokasta perityn version. Ideana tässä on, että saamme perityn naytatilavuus()-funktion kutsumaan periytetyn luokan versiota tilavuus()-funktiosta, kun kutsumme sitä VahvaLtk-luokan oliosta. Katsotaan, kuinka se toimii. 625

6 C++ Ohjelmoijan käsikirja Kokeile itse - Periytetyn luokan käyttö Voimme testata uutta periytettyä luokkaamme yksinkertaisesti luomalla Laatikko-olion ja VahvaLtk-olion, joiden mitat ovat samat, ja vertaamalla, onko niiden lasketut tilavuudet samat. Tämän tekevä main()-funktio näyttää seuraavalta: // Esimerkki 16.1 Perittyjen funktioiden toiminta periytetyssä luokassa #include <iostream> #include "Laatikko.h" // Laatikko-luokka #include "VahvaLtk.h" // VahvaLtk-luokka using namespace std; int main() Laatikko omaltk(20.0, 30.0, 40.0); // Esitellään kantaluokka VahvaLtk vahval(20.0, 30.0, 40.0); // Esitellään periytetty laatikko - sama koko cout << endl; omaltk.naytatilavuus(); // Näytetään kantaluokan laatikon tilavuus vahval.naytatilavuus(); // Näytetään periytetyn luokan laatikon tilavuus return 0; Kun suoritan ohjelman, se tulostaa: Laatikon käytettävissä oleva tilavuus on Laatikon käytettävissä oleva tilavuus on Kuinka se toimii Periytetyn luokan olion tilavuuden pitäisi olla pienempi kuin kantaluokan olion, joten ohjelmamme ei toimi niin kuin pitäisi. Yritetään saada selville, missä menee väärin. Funktion naytatilavuus() toinen kutsu on periytetyn luokan oliolle VahvaLtk, mutta selvästikään tätä ei oteta huomioon. VahvaLtk-olion tilavuuden tulisi olla 85% tavallisen samankokoisen Laatikkoolion tilavuudesta. Ongelmana on se, että kun tilavuus()-funktiota kutsutaan naytatilavuus()-funktiosta, kääntäjä kutsuu aina kantaluokan tilavuus()-funktiota. Sillä ei ole vaikutusta, miten naytatilavuus()- funktiota kutsutaan, se ei koskaan kutsu VahvaLtk-luokan versiota tilavuus()-funktiosta. Kun funktioiden kutsut ovat tällä tavalla kiinteät jo ennen ohjelman suoritusta, funktion kutsua kutsutaan staattiseksi sidonnaksi. Termiä aikainen sidonta käytetään myös usein. Tässä esimerkissä tietty tilavuus()-funktio sidotaan funktioon naytatilavuus() ohjelman suorituksen aikana. Joka kerta, kun naytatilavuus()-funktiota kutsutaan, kutsutaan kantaluokan tilavuus()-funktiota, joka siihen on sidottu. 626

7 Virtuaalifunktiot ja polymorfismi! Samanlainen sidonta tapahtuu myös periytetyssä luokassa VahvaLtk, jos asetamme ehdot oikein. Eli jos lisäämme naytatilavuus()-funktion (joka kutsuu tilavuus()- funktiota) VahvaLtk-luokkaan, tilavuus()-funktion kutsu sidottaisiin staattisesti periytetyn luokan funktioon. Entäpä jos kutsummekin tilavuus()-funktiota suoraan VahvaLtk-oliosta? Lisätään lauseet, jotka kutsuvat tilavuus()-funktiota suoraan VahvaLtk-oliosta kantaluokan osoittimen avulla: cout << vahval:n tilavuus on << vahval.tilavuus() << endl; Laatikko *pltk = &vahval; cout << vahval:n tilavuus pltk:n kautta on << pltk->tilavuus() << endl; Lisää nämä lauseet main()-funktioon juuri ennen return-lausetta. Kun suoritat ohjelman, saat tulostuksena: Laatikon käytettävissä oleva tilavuus on Laatikon käytettävissä oleva tilavuus on vahval:n tilavuus on vahval:n tilavuus pltk:n kautta on Tämä on varsin informatiivinen. Kuten huomaamme, periytetyn luokan tilavuus()-funktion kutsu kutsuu periytetyn luokan tilavuus()-funktiota, mitä juuri halusimmekin. Kutsu kantaluokan osoittimen pltk avulla kutsuu kuitenkin kantaluokan versiota tilavuus()-funktiosta, vaikka pltk sisältää vahval:n osoitteen. Toisin sanoen molemmat kutsut sidotaan staattisesti. Kääntäjä toteuttaa nämä kutsut seuraavasti: cout << vahval:n tilavuus on << vahval.vahvaltk::tilavuus() << endl; Laatikko *pltk = &vahval; cout << vahval:n tilavuus pltk:n kautta on << pltk->laatikko::tilavuus() << endl; Funktion staattinen kutsu osoittimen avulla ratkaistaan pelkästään osoittimen tyypin perusteella eikä osoitetun olion perusteella. Osoitin pltk on tyyppiä osoitin Laatikko-olioon, joten kaikki staattiset kutsut pltk:n avulla kutsuvat Laatikko-luokan jäsenfunktiota. Kaikki kantaluokan staattisesti sidotun osoittimen avulla kutsutut funktiot kutsuvat kantaluokan funktiota. Haluamme esimerkkimme avulla selvittää, mitä tilavuus()-funktiota missäkin tilanteessa käytetään. Eli, jos kutsumme naytatilavuus()-funktiota periytetyn luokan oliosta, haluamme, että kutsutaan periytetyn luokan tilavuus()-funktiota, ei kantaluokan versiota. Vastaavasti, jos kutsumme tilavuus()-funktiota kantaluokan osoittimen avulla, haluamme, että kutsutaan osoitetulle oliolle sopivaa funktiota. Tällaista kutsutaan dynaamiseksi sidonnaksi tai myöhäiseksi sidonnaksi. Ohjelma ei kuitenkaan vielä toimi haluamallamme tavalla, koska meidän täytyy kertoa kääntäjälle, että tilavuus()-funktio Laatikko-luokassa ja siitä periytetyissä luokissa on erikoinen. Haluamme, että kutsut ratkaistaan dynaamisesti. Nyt meidän tulee määritellä tilavuus()- funktio virtuaalifunktioksi. 627

8 C++ Ohjelmoijan käsikirja Virtuaalifunktiot Kun esittelet funktion kantaluokassa virtuaaliseksi, kerrot kääntäjälle, että haluat funktion sidottavan dynaamisesti kaikista kyseisestä kantaluokasta periytetyissä luokissa. Virtuaalifunktio esitellään kantaluokassa virtual-avainsanalla. class Laatikko public: virtual double tilavuus() const... ; class PahviLaatikko: public Laatikko public: virtual double tilavuus() const... ; class VahvaLtk: public Laatikko public: virtual double tilavuus() const... ; class MuuLtk: public Laatikko public: virtual double tilavuus() const... ; PLtk on tyyppiä osoitin Laatikko-olioon. Kutsuttava tilavuus() -funktion versio riippuu sen olion tyypistä, johon pltk osoittaa double tulos = pltk->tilavuus(); Funktio, jonka esittelet virtuaaliseksi kantaluokassa, on virtuaalinen kaikissa kantaluokasta periytetyissä (joko suorissa tai epäsuorissa) luokissa. Jotta polymorfisminen toiminta saadaan aikaan, jokainen periytetty luokka voi toteuttaa oman virtuaalifunktion (vaikka se ei pakollista olekaan; palaamme tähän kohta). Virtuaalifunktion kutsut voidaan suorittaa muuttujan, joka on osoitin tai viittaus kantaluokan olioon, avulla. Yllä oleva kaavio havainnollistaa, miten virtuaalifunktion kutsu osoittimen avulla ratkaistaan dynaamisesti. Osoitinta kantaluokkaan käytetään tallettamaan jonkin periytetyn luokan olion osoite. Se voi osoittaa mihin tahansa kolmesta periytetystä luokasta tai luonnollisestikin kantaluokan olioon. Mitä tilavuus()- funktiota milloinkin kutsutaan, riippuu osoittimen kutsuhetkellä osoittaman olion tyypistä. Luokan määrittely polymorfistiseksi tarkoittaa, että se on periytetty luokka, jossa on vähintään yksi virtuaalifunktio. Ennen kuin siirrymme eteenpäin, huomaa, että virtuaalifunktion kutsu olion avulla ratkaistaan aina staattisesti. Virtuaalifunktion kutsu ratkaistaan dynaamisesti vain silloin, kun kutsu tapahtuu osoittimen tai viittauksen avulla. Nyt voimme testata virtuaalifunktioita. 628

9 Virtuaalifunktiot ja polymorfismi Kokeile itse - Virtuaalifunktioiden käyttö Meidän tulee muuttaa edellisen esimerkkimme Laatikko-luokkaa hieman, jotta saamme esimerkin toimimaan haluamallamme tavalla. Meidän tulee lisätä virtual-avainsana tilavuus()-funktion esittelyyn: class Laatikko public: Laatikko(double pitarvo = 1.0, double syvarvo = 1.0, double korkarvo = 1.0); // Funktio, joka näyttää olion tilavuuden void naytatilavuus() const; // Funktio, joka laskee Laatikko-olion tilavuuden virtual double tilavuus() const; protected: double pituus; double syvyys; double korkeus; ; Huomaa, että sinun ei tarvitse lisätä virtual-avainsanaa funktion määrittelyyn. Itse asiassa olisi virhe tehdä niin. Jotta saamme esimerkin vielä kiinnostavammaksi, toteutamme tilavuus()-funktion uuteen PahviLaatikko-luokkaan hieman eri tavalla: // Pahvil.h #ifndef PAHVILAATIKKO_H #define PAHVILAATIKKO_H #include <string> #include "Laatikko.h" using std::string; class PahviLaatikko : public Laatikko public: // Muodostinfunktio, joka kutsuu kantaluokan muodostinfunktiota PahviLaatikko(double pa, double sa, double ka, string materiaali = "Pahvi"); // Kopiomuodostin PahviLaatikko(const PahviLaatikko& apahviltk); // Tuhoajafunktio ~PahviLaatikko(); // Funktio, joka laskee PahviLaatikko-olion tilavuuden double tilavuus() const; 629

10 C++ Ohjelmoijan käsikirja private: string* pmateriaali; ; #endif // Pahvil.cpp #include "Pahvil.h" PahviLaatikko::PahviLaatikko(double pa, double sa, double ka, string materiaali) : Laatikko(pa, sa, ka) pmateriaali = new string(materiaali); PahviLaatikko::PahviLaatikko(const PahviLaatikko& apahviltk) pituus = apahviltk.pituus; syvyys = apahviltk.syvyys; korkeus = apahviltk.korkeus; pmateriaali = new string(*apahviltk.pmateriaali); PahviLaatikko::~PahviLaatikko() delete pmateriaali; double PahviLaatikko::tilavuus() const double til = (pituus - 0.5) * (syvyys - 0.5) * (korkeus - 0.5); return til > 0.0? til : 0.0; PahviLaatikko-luokan tilavuus()-funktio olettaa, että materiaalin paksuus on 0.25, joten 0.5 vähennetään jokaisesta mitasta. Jos PahviLaatikko-olio on jostain syystä luotu siten, että jokin mitta on pienempi kuin 0.5, tilavuudeksi lasketaan 0. Käytämme myöskin esimerkissä 16.1 määriteltyä VahvaLtk-luokkaa. Voimme nyt muuttaa edellisen esimerkin main()-funktiota ottamalla PahviLaatikko-olion käsittelyyn mukaan. Kutsumme myöskin naytatilavuus()-funktiota pltk-osoittimen avulla: // Laatikko-luokka // VahvaLtk-luokka // PahviLaatikko- // Esimerkki 16.2 Virtuaalifunktioiden käyttö #include <iostream> #include "Laatikko.h" #include "VahvaLtk.h" #include "Pahvil.h" luokka using namespace std; 630 int main() Laatikko omaltk(20.0, 30.0, 40.0); // Esitellään kantalaatikko VahvaLtk vahval(20.0, 30.0, 40.0); // Esitellään periytetty laatikko - sama koko PahviLaatikko apahviltk(20.0, 30.0, 40.0); // Toinen periytetty laatikko

11 Virtuaalifunktiot ja polymorfismi cout << endl; omaltk.naytatilavuus(); vahval.naytatilavuus(); apahviltk.naytatilavuus(); cout << endl; // Näytetään kantalaatikon tilavuus // Näytetään periytetyn laatikon tilavuus // Näytetään periytetyn laatikon tilavuus // Nyt kokeillaan kantaluokan osoitinta Laatikko-oliolle Laatikko* pltk = &omaltk; // Osoittaa tyyppiin Laatikko cout << "omaltk:n tilavuus pltk:n kautta on " << pltk->tilavuus() << endl; pltk->naytatilavuus(); cout << endl; // Nyt kokeillaan kantaluokan osoitinta VahvaLtk-oliolle pltk = &vahval; // Osoittaa tyyppiin Laatikko cout << "vahval:n tilavuus pltk:n kautta on " << pltk->tilavuus() << endl; pltk->naytatilavuus(); cout << endl; // Nyt kokeillaan kantaluokan osoitinta PahviLaatikko-oliolle pltk = &apahviltk; // Osoittaa tyyppiin Laatikko cout << "apahviltk:n tilavuus pltk:n kautta on " << pltk->tilavuus() << endl; pltk->naytatilavuus(); return 0; Voit nyt kääntää esimerkin uudelleen. Kun suoritat sen, tulostuksen tulisi näyttää seuraavalta: Laatikon käytettävissä oleva tilavuus on Laatikon käytettävissä oleva tilavuus on Laatikon käytettävissä oleva tilavuus on omaltk:n tilavuus pltk:n kautta on Laatikon käytettävissä oleva tilavuus on vahval:n tilavuus pltk:n kautta on Laatikon käytettävissä oleva tilavuus on apahviltk:n tilavuus pltk:n kautta on Laatikon käytettävissä oleva tilavuus on ! Kuinka se toimii Avainsana virtual kantaluokan tilavuus()-funktion yhteydessä on riittävä määrittely, jotta kaikki tilavuus()-funktiot periytetyissä luokissa ymmärretään myös virtuaalisiksi. Voit halutessasi käyttää virtual-avainsanaa periytettyjen luokkien funktioiden yhteydessä - kuten edellisessä kaaviossa havainnollistettiin. Tässä esimerkissä jätimme virtual-avainsanan pois tilavuus()-funktioiden määrittelyistä havainnollistaaksemme, että sen käyttö ei ole pakollista. Suosittelen kuitenkin, että käytät virtual-avainsanaa kaikissa periytettyjen luokkien virtuaalifunktioiden esittelyissä, koska se tekee periytetyn luokan esittelyä lukevalle selväksi, että funktio on itse asiassa virtuaalinen ja että se sidotaan dynaamisesti. 631

12 C++ Ohjelmoijan käsikirja Ohjelma tekee selvästikin nyt sen, mitä halusimmekin. Funktion naytatilavuus() ensimmäinen kutsu Laatikko-tyyppiselle oliolle omaltk on seuraava: omaltk.naytatilavuus(); // Näytetään kantalaatikon tilavuus Tämä yksinkertaisesti kutsuu kantaluokan versiota tilavuus()-funktiosta, koska omaltk on tyyppiä Laatikko. Seuraava naytatilavuus()-funktion kutsu on VahvaLtk-tyyppiselle oliolle vahval: vahval.naytatilavuus(); // Näytetään periytetyn laatikon tilavuus Tämä lause kutsuu Laatikko-luokassa määriteltyä naytatilavuus()-funktiota - itse asiassa naytatilavuus()-funktiosta ei ole muuta versiota. Funktio on peritty VahvaLtk-luokan julkisena jäsenenä, joten sitä voidaan kutsua tällä tavalla. Funktion tilavuus() kutsu naytatilavuus()- funktiossa sidotaan periytetyssä luokassa määriteltyyn versioon, koska tilavuus() on virtuaalifunktio. Saamme näin oikein lasketun tilavuuden VahvaLtk-oliolle. Kolmas naytatilavuus()-funktion kutsu on PahviLaatikko-oliolle: apahviltk.naytatilavuus(); // Näytetään periytetyn laatikon tilavuus 632 Funktio naytatilavuus() on peritty PahviLaatikko-luokkaan ja tilavuus()-funktion kutsu sidotaan PahviLaatikko-luokan versioon, joten saamme jälleen oikein lasketun tilavuuden. Seuraavaksi kutsumme pltk-osoittimen avulla tilavuus()-funktiota suoraan sekä epäsuorasti naytatilavuus()-funktion kautta. Osoitin sisältää aluksi Laatikko-olion omaltk osoitteen ja sen jälkeen kahden periytetyn olion osoitteen. Kunkin olion tulostus näyttää, että oikea versio tilavuus()-funktiosta valitaan automaattisesti jokaisessa tilanteessa. Eli kyseessä on täydellisen polymorfismin esimerkki. Virtuaalifunktion vaatimukset Jotta funktio toimii virtuaalisesti, sinun tulee esitellä ja määritellä se periytetyssä luokassa saman nimiseksi kuin kantaluokassa ja sen parametriluettelon tulee olla sama kuin kantaluokassa. Lisäksi, jos olet esitellyt kantaluokan funktion const-tyyppiseksi, tulee sinun esitellä periytetyn luokan funktio myös const-tyyppiseksi. Yleensä periytetyn luokan funktion paluuarvon tyypin tulee olla sama kuin kantaluokassa, mutta tähän on poikkeus, kun kantaluokan funktion paluuarvo on osoitin tai viittaus luokkatyyppiin. Tällöin periytetyn luokan versio virtuaalifunktiosta voi palauttaa osoittimen tai viittauksen muuhunkin tyyppiin kuin kantaluokan tyyppiin. Emme käsittele tätä tämän enempää. Voit päätellä virtuaalifunktioiden määrittelyn säännöistä, että jos yrität käyttää eri parametrejä periytetyn luokan virtuaalifunktiossa, kuin mitä käytit kantaluokassa, virtuaalifunktion mekanismi ei toimi. Periytetyn luokan funktio sidotaan tällöin staattisesti käännösaikana. Näin on myös silloin, jos unohdat esitellä periytetyn luokan funktion const-tyyppiseksi, jos kantaluokan funktio on const-tyyppinen. Voit testata tätä poistamalla const-avainsanan PahviLaatikko-luokassa olevan tilavuus()- funktion esittelystä ja suorittamalla edellisen esimerkin uudelleen. Tämä tarkoittaa sitä, että PahviLaatikko-luokan tilavuus()-funktio ei enää täsmää Laatikko-luokassa esiteltyä

13 Virtuaalifunktiot ja polymorfismi virtuaalifunktiota, joten periytetyn luokan tilavuus()-funktio ei ole virtuaalinen. Näin ollen sidonta on staattinen, eli PahviLaatikko-luokan kohdalla kutsuttava funktio on kantaluokan versio, kun kutsutaan kantaluokan osoittimen avulla tai epäsuorasti naytatilavuus()-funktion kautta. Jos periytetyn funktion nimi ja parametriluettelo ovat samat kuin kantaluokassa esitetyllä virtuaalifunktiolla, paluuarvon tyypin pitää olla virtuaalifunktion sääntöjen mukainen. Jos se ei ole, periytetyn luokan funktio ei käänny. Tässä yhteydessä haluan lisätä pienen varoituksen, että älä koskaan esittele virtuaalifunktiota avoimeksi (inline). Avointen funktioiden tarkoitus on se, että ne korvataan käännösaikana, joten virtuaalifunktio ei voi olla avoin. Sinun tulee aina esitellä virtuaalifunktiot virtuaalisiksi. Virtuaalifunktiot ja luokkahierarkia Jos haluat, että funktiotasi kohdellaan virtuaalisena kantaluokan osoittimen kanssa, sinun tulee esitellä se virtuaaliseksi kantaluokassa. Voit esitellä kantaluokassa niin monta virtuaalifunktiota kuin haluat, mutta kaikkia virtuaalifunktioita ei tarvitse esitellä virtuaalisiksi kaikkein ylimmässä kantaluokassa. Tätä havainnollistetaan seuraavassa kaaviossa. class Laatikko virtual double tilavuus(); Class PahviLaatikko: public Laatikko virtual double tilavuus(); virtual void teetuo(int i); class VahvaLtk: public Laatikko virtual double tilavuus(); virtual string teetama(int i); class SaleLtk: public PahviLaatikko virtual void teetuo(int i); Perii tilavuus() -funktion PahviLaatikko-luokasta class SuuriLtk: public VahvaLtk virtual string teetama(int i); Perii tilavuus() -funktion VahvaLtk- luokasta class PieniLtk: public vahvaltk virtual double tilavuus(); virtual string teetama(int i); class Paketti: public PahviLaatikko virtual double tilavuus(); virtual void teetuo(int i); Tilavuus() On virtuaalinen kaikissa luokissa. TeeTuo() On virtuaalinen PahviLaatikko- SaleLtk- ja Pakettiluokissa TeeTama() On virtuaalinen VahvaLtk-, SuuriLtk- ja PieniLtkluokissa Kun esittelet funktion virtuaaliseksi yhdessä luokassa, funktio on virtuaalinen kaikissa luokissa, jotka on periytetty suoraan tai epäsuoraan tästä luokasta. Esimerkiksi kaikki luokat, jotka on periytetty Laatikko-luokasta, perivät tilavuus()-funktion virtuaalisena. Voit kutsua näiden luokkien tilavuus()-funktiota Laatikko*-tyyppisen osoittimen pltk avulla, koska osoitin voi sisältää minkä tahansa hierarkiassa olevan olion osoitteen: double tulos = pltk->tilavuus(); //Kutsuu minkä tahansa luokan funktiota SaleLtk-luokassa ei esitellä virtuaalifunktiota tilavuus(), joten PahviLaatikko-luokalta perittyä versiota käytetään SaleLtk-olioiden kohdalla. Se on peritty virtuaalifunktiona, joten sitä kutsutaan polymorfistisesti. 633

14 C++ Ohjelmoijan käsikirja Tyyppiä PahviLaatikko* olevaa osoitinta ppahviltk voidaan käyttää kutsuttaessa tilavuus()-funktiota, mutta vain PahviLaatikko-luokan kohdalla tai SaleLtk- ja Pakettiluokkien kohdalla, joiden kantaluokkana on PahviLaatikko: tulos = ppahviltk->tilavuus() //PahviLaatikko-, SaleLtk- ja Paketti-luokista PahviLaatikko-luokka ja siitä periytetyt luokat sisältävät myös virtuaalifunktion teetuo(). Tätä funktiota voidaan kutsua polymofistisesti PahviLaatikko*-tyyppisen osoittimen avulla: ppahviltk->teetuo(12); //PahviLaatikko-, SaleLtk- ja Paketti-luokista Huomaa, että et voi kutsua näiden luokkien teetuo()-funktiota käyttämällä osoitinta pltk, koska Laatikko-luokka ei sisällä funktiota teetuo(). Vastaavasti virtuaalifunktiota teetama() voidaan kutsua luokista VahvaLtk, SuuriLtk ja PieniLtk käyttämällä kantaluokan osoitinta pvahvaltk: string vastaus = pvahvaltk-teetama(3); //VahvaLtk-, SuuriLtk- ja PieniLtk-luokista Luonnollisestikin samaa osoitinta voidaan käyttää kutsuttaessa näiden luokkien tilavuus()- funktioita. Saantitavat ja virtuaalifunktiot Periytetyn luokan virtuaalifunktion saantitapa voi olla eri kuin saantitapa kantaluokassa. Kun kutsut virtuaalifunktiota osoittimen kautta, kantaluokan saantitapa ratkaisee, onko funktio kutsuttavissa periytetystä luokasta. Jos virtuaalifunktio on kantaluokassa julkinen, sitä voidaan kutsua kantaluokan osoittimen (tai viittauksen) avulla kaikkien periytettyjen luokkien kohdalla, riippumatta periytettyjen luokkien saantitavasta. Voimme havainnollistaa tätä muuttamalla hieman edellistä esimerkkiä. Kokeile itse - Virtuaalifunktioiden saantitavan vaikutus Muuta edellisen esimerkin VahvaLtk-luokan määrittelyä muuttamalla tilavuus()-funktio suojatuksi ja lisäämällä virtual-avainsana sen esittelyyn: class VahvaLtk : public Laatikko // Periytetty luokka public: // Muodostinfunktio VahvaLtk(double pituusarvo, double syvyysarvo, double korkeusarvo); protected: // Funktio, joka laskee VahvaLtk:n tilavuuden (15% menee laatikolle) virtual double tilavuus() const; ; main()-funktiota tulee myös muuttaa hieman: 634

15 Virtuaalifunktiot ja polymorfismi // Laatikko-luokka // VahvaLtk-luokka // PahviLaatikko- // Esimerkki 16.3 Saantitavat ja virtuaalifunktiot #include <iostream> #include "Laatikko.h" #include "VahvaLtk.h" #include "Pahvil.h" luokka using namespace std; int main() Laatikko omaltk(20.0, 30.0, 40.0); // Esitellään kantalaatikko VahvaLtk vahval(20.0, 30.0, 40.0); // Esitellään periytetty laatikko - sama koko PahviLaatikko apahviltk(20.0, 30.0, 40.0);// Toinen periytetty laatikko cout << endl; omaltk.naytatilavuus(); // Näytetään kantalaatikon tilavuus vahval.naytatilavuus(); // Näytetään periytetyn laatikon tilavuus apahviltk.naytatilavuus(); // Näytetään periytetyn laatikon tilavuus cout << endl; //cout << "vahval:n tilavuus on " << vahval.tilavuus() << endl; //Poista kommentointi niin saat virheen! // Nyt kokeillaan kantaluokan osoitinta Laatikko-oliolle Laatikko* pltk = &omaltk; // Osoittaa tyyppiin Laatikko cout << "omaltk:n tilavuus pltk:n kautta on " << pltk->tilavuus() << endl; pltk->naytatilavuus(); cout << endl; // Nyt kokeillaan kantaluokan osoitinta VahvaLtk-oliolle pltk = &vahval; // Osoittaa tyyppiin Laatikko cout << "vahval:n tilavuus pltk:n kautta on " << pltk->tilavuus() << endl; pltk->naytatilavuus(); cout << endl; // Nyt kokeillaan kantaluokan osoitinta PahviLaatikko-oliolle pltk = &apahviltk; // Osoittaa tyyppiin Laatikko cout << "apahviltk:n tilavuus pltk:n kautta on " << pltk->tilavuus() << endl; pltk->naytatilavuus(); return 0; Ei varmastikaan ole yllätys, että tämä koodi tuottaa saman tulostuksen kuin edellinenkin esimerkki. Kuinka se toimii Vaikka tilavuus()-funktio on esitelty suojatuksi VahvaLtk-luokassa, voimme silti kutsua sitä vahval-olion kohdalla naytatilavuus()-funktion kautta, joka on peritty Laatikko-luokasta. Voimme kutsua sitä myös kantaluokan osoittimen pltk avulla. Jos kuitenkin poistat kommentoinnin riviltä, jossa kutsutaan tilavuus()-funktiota suoraan vahval-olion kautta, koodi ei käänny. Tässä vaikuttaa se, sidotaanko kutsu dynaamisesti vai staattisesti. Kun käytät luokan oliota, kutsu sidotaan staattisesti (eli kääntäjän toimesta) ja koska tilavuus()-funktio on suojattu 635

16 C++ Ohjelmoijan käsikirja VahvaLtk-oliossa, kutsu vahval-olion kautta ei käänny. Kaikki muut kutsut sidotaan ohjelman suorituksen aikana - ne ovat polymorfistisia funktiokutsuja. Tällöin kantaluokan virtuaalifunktion saantitapa periytyy kaikkiin periytettyihin luokkiin. Tämä siitä huolimatta, että saantitapa on määritelty eksplisiittisesti periytetyssä luokassa: eksplisiittinen määrittely on voimassa vain staattisesti sidotuissa funktiokutsuissa. Parametrien oletusarvot virtuaalifunktioissa Koska oletusarvot käsitellään käännösaikana, voit saada odottamattomia vaikutuksia, jos käytät virtuaalifunktiossa parametrien oletusarvoja. Jos kantaluokan virtuaalifunktion esittelyssä on parametreillä oletusarvoja, ja kutsut funktiota kantaluokan osoittimen avulla, saat aina oletusparametrin arvon kantaluokan versiosta. Periytetyn luokan version parametrien oletusarvoilla ei ole vaikutusta. Voimme havainnollistaa tätä muuttamalla edellistä esimerkkiä lisäämällä tilavuus()-funktion parametrille oletusarvon. Kokeile itse - Parametrien oletusarvot Muuta Laatikko.cpp-tiedostossa olevaa tilavuus()-funktion esittelyä seuraavasti: double Laatikko::tilavuus(const int i) const cout << "Parametri = " << i << endl; return pituus * syvyys * korkeus; Muuta hieman myös funktion esittelyä Laatikko-luokassa: // Funktio, joka laskee Laatikko-olion tilavuuden virtual double tilavuus(const int i = 5) const; Parametrillä ei ole muuta tarkoitusta kuin havainnollistaa, miten oletusarvoja käsitellään. Muuta PahviLaatikko-luokkaa samalla tavalla, mutta anna parametrin oletusarvoksi 50 ja VahvaLtkluokassa oletusarvoksi 500. Voit lisäksi palauttaa VahvaLtk-luokan tilavuus()-funktion saantitavaksi julkisen. Äläkä unohda, että sinun tulee sisällyttää iostream-otsikkotiedosto kahteen cpptiedostoon. Tekemällä nämä muutokset luokkien määrittelyihin, voimme kokeilla oletusarvoja edellä näkemällämme main()-funktiolla, jossa kommentoimme rivin, jossa kutsutaan vahval-olion tilavuus()-funktiota suoraan. Saat seuraavanlaisen tulostuksen: Parametri = 5 Laatikon käytettävissä oleva tilavuus on Parametri = 5 Laatikon käytettävissä oleva tilavuus on Parametri = 5 Laatikon käytettävissä oleva tilavuus on Parametri = 500 vahval:n tilavuus on Parametri = 5 omaltk:n tilavuus pltk:n kautta on 24000

17 Virtuaalifunktiot ja polymorfismi Parametri = 5 Laatikon käytettävissä oleva tilavuus on Parametri = 5 vahval:n tilavuus pltk:n kautta on Parametri = 5 Laatikon käytettävissä oleva tilavuus on Parametri = 5 apahviltk:n tilavuus pltk:n kautta on Parametri = 5 Laatikon käytettävissä oleva tilavuus on Kuinka se toimii Yhtä kutsua lukuun ottamatta tulostettu oletusarvo on peräisin kantaluokan funktiosta. Poikkeuksena on, kun kutsumme tilavuus()-funktiota vahval-olion avulla. Tämä sidotaan staattisesti, joten VahvaLtk-luokan parametrin oletusarvoa käytetään. Kaikki muut kutsut sidotaan dynaamisesti, joten kantaluokan oletusarvoa käytetään. Viittausten käyttö kutsuttaessa virtuaalifunktioita Voit kutsua virtuaalifunktioita myös viittauksen avulla ja viittausparametrit ovat tehokas tapa polymorfismin soveltamisessa. Virtuaalifunktion kutsumisella viittaustyyppisen muuttujan avulla ei ole samaa taikaa kuin osoittimen avulla kutsuttaessa, koska viittausmuuttuja alustetaan vain kerran ja ne voivat näin ollen kutsua vain sen olion funktioita. Funktion viittausparametrit ovat kuitenkin eri asia. Oletetaan, että määrittelet funktion, jonka parametri on viittaus kantaluokkaan. Voit tällöin välittää periytetyn luokan olion funktiolle parametrinä. Funktiossa voit käyttää viittausparametriä virtuaalifunktion kutsumisessa. Kun funktiotasi suoritetaan, välitetylle oliolle sopiva virtuaalifunktio valitaan automaattisesti. Näemme, miten tämä toimii, kun muutamme esimerkin 16.2 main()-funktiota siten, että se kutsuu funktiota, jonka parametri on tyyppiä viittaus Laatikko-olioon. Kokeile itse - Viittausten käyttö virtuaalifunktioissa Tässä esimerkissä lisäämme uuden, erillisen globaalin funktion naytatilavuus(), joka tulostaa olion tilavuuden. Välitämme sille viittausparametrin, jota käytämme olion naytatilavuus()- funktiota kutsuessamme. Funktion määrittely on seuraava: void naytatilavuus(const Laatikko& rltk) rltk.naytatilavuus(); Voimme kutsua tätä funktiota main()-funktiostamme ja välittää sille parametrinä viittauksia periytettyjen luokkien olioihin. Ainoat muutokset, jotka sinun tulee tehdä luokkien määrittelyihin, ovat tilavuus()-jäsenfunktioiden määrittelyt, joista sinun tulee poistaa parametri i ja i:n tulostavat rivit. Meidän tulee muuttaa main()-funktiota seuraavasti: 637

18 C++ Ohjelmoijan käsikirja // Esimerkki 16.5 Virtuaalifunktioiden käyttö viittausten kautta #include <iostream> #include "Laatikko.h" // Laatikko-luokka #include "VahvaLtk.h" // VahvaLtk-luokka #include "Pahvil.h" // PahviLaatikkoluokka using namespace std; void naytatilavuus(const Laatikko& rltk); // Globaalin funktion prototyyppi int main() Laatikko omaltk(20.0, 30.0, 40.0); // Esitellään kantalaatikko VahvaLtk vahval(20.0, 30.0, 40.0); // Esitellään periytetty laatikko - sama koko PahviLaatikko apahviltk(20.0, 30.0, 40.0);// Toinen periytetty laatikko cout << endl; naytatilavuus(omaltk); naytatilavuus(vahval); naytatilavuus(apahviltk); cout << endl; // Näytetään kantalaatikon tilavuus // Näytetään periytetyn laatikon tilavuus // Näytetään periytetyn laatikon tilavuus // Rivit poistettu return 0; // Globaali funktio, joka näyttää laatikon tilavuuden void naytatilavuus(const Laatikko& rltk) rltk.naytatilavuus(); Esimerkin suorittaminen saa aikaan tulostuksen: Laatikon käytettävissä oleva tilavuus on Laatikon käytettävissä oleva tilavuus on Laatikon käytettävissä oleva tilavuus on Kuinka se toimii Funktiossa main() luomme kantaluokan olion omaltk ja kaksi eri periytetyn luokan oliota vahval ja apahviltk. Tämän jälkeen kutsumme globaalia naytatilavuus()-funktiota, kukin olio vuorollaan parametrinä. Kuten tulostuksesta huomaat, jokaisessa tapauksessa kutsutaan oikeaa tilavuus()-funktiota. Eli polymorfismi toimii viittausparametrin välityksellä. Joka kerta, kun funktiota kutsutaan, viittausparametri alustetaan parametrinä välitetyn olion mukaan. Koska parametri on viittaus kantaluokan olioon, kääntäjä tekee suoritusaikana sidonnan virtuaaliseen tilavuus()-funktioon. Jos olisit määritellyt parametrin viittaukseksi periytettyyn luokkaan, funktiokutsu olisi sidottu staattisesti, koska se olisi ollut täydellisesti määritelty. Dynaaminen sidonta suoritetaan vain, jos kutsu suoritetaan kantaluokan viittauksen avulla. 638

19 Virtuaalifunktiot ja polymorfismi Virtuaalifunktion kantaluokan version kutsuminen Olemme jo nähneet, kuinka helppoa on periytetyn luokan olion osoittimen tai viittauksen avulla kutsua periytetyn luokan versiota virtuaalifunktiosta - kutsut sidotaan tällöin dynaamisesti. Mutta mitä meidän tarvitsee tehdä samassa tilanteessa, jos haluammekin kutsua kantaluokan funktiota periytetyn luokan olion avulla? Laatikko-luokassa on tilanne, jossa saattaisimme haluta kutsua kantaluokan funktiota. Saattaisi olla hyödyllistä laskea tilavuuden ero PahviLaatikko- tai VahvaLtk-olioiden kohdalla verrattuna Laatikko-olioon. Yksi tapa tämän suorittamiseen on laskea erotus kantaluokan ja periytetyn luokan tilavuus()-funktion palauttamien tulosten välillä. Voit pakottaa, että kantaluokan virtuaalifunktiota kutsutaan staattisesti, kun käytät luokan nimeä yhdessä näkyvyysalueoperaattorin kanssa. Oletetaan, että meillä on osoitin pltk, joka on määritelty seuraavasti: PahviLaatikko apahviltk(40.0, 30.0, 20.0); Laatikko* pltk = &apahviltk; Voimme laskea tilavuuksien erotuksen PahviLaatikko-olion kohdalla seuraavasti: double erotus = pltk->laatikko::tilavuus() - pltk->tilavuus(); Lauseke pltk->laatikko::tilavuus() kutsuu kantaluokan versiota tilavuus()-funktiosta. Luokan nimi yhdessä näkyvyysalueoperaattorin kanssa määrittelee tietyn tilavuus()-funktion, joten kyseessä on staattinen sidonta, joka ratkaistaan käännösaikana.! Näkyvyysalueoperaattorin avulla voit kutsua kantaluokan versiota mistä tahansa jäsenfunktiosta, jos saantitapa sallii funktion kutsumisen. Huomaa, että et voi käyttää tätä tekniikkaa tietyn periytetyn luokan funktion kutsumiseen osoittimen avulla. Lauseke pltk->pahvilaatikko::tilavuus() ei käänny, koska PahviLaatikko::tilavuus() ei ole Laatikko-luokan jäsen. Kun kutsut funktiota osoittimen avulla, kutsu on joko staattinen, osoitettavan luokan jäsenfunktion kutsu tai dynaaminen virtuaalifunktion kutsu. Kantaluokan virtuaalifunktion kutsuminen periytetyn luokan olion avulla on myöskin helppoa. Voit käyttää static_cast-muunnosta periytetystä luokasta kantaluokkaan ja käyttää muunnoksen tulosta kantaluokan funktion kutsumiseen. Voimme laskea tilavuuden erotuksen apahviltk-olion kohdalla lauseella: double erotus = static_cast<laatikko>(apahviltk).tilavuus() - apahviltk.tilavuus(); Tämän lauseen molemmat funktiokutsut sidotaan staattisesti. Muuntamalla apahviltk Laatikko-tyyppiseksi, kutsuttava funktio on Laatikko-luokan tilavuus()-funktio. Virtuaalifunktioiden kutsut olion avulla sidotaan aina staattisesti. 639

20 C++ Ohjelmoijan käsikirja Olioiden osoittimien muuntaminen Jos ohjelmassasi on osoitin periytettyyn luokkaan, voit helposti muuntaa sen osoittimeksi kantaluokkaan. Tämä voidaan tehdä sekä suorien että epäsuorien kantaluokkien kohdalla. Esitellään esimerkiksi osoitin PahviLaatikko-luokkaan seuraavasti: PahviLaatikko* ppahviltk = new PahviLaatikko(30, 40, 10); Voimme muuntaa tämän osoittimen automaattisesti PahviLaatikko-luokan suoran kantaluokan osoittimeksi (Laatikko-luokkahan on PahviLaatikko-luokan suora kantaluokka): Laatikko* pltk = ppahviltk; Tuloksena on osoitin Laatikko-olioon, joka alustetaan osoittamaan uuteen PahviLaatikko-olioon. Voimme automaattisesti muuntaa periytetyn luokan olion osoittimen epäsuoran kantaluokan osoittimeksi. Oletetaan, että meillä on viereisen kaavion mukainen hierarkia: class Laatikko class PahviLaatikko: public Laatikko class KauraLtk: public PahviLaatikko Tässä Laatikko on PahviLaatikko-luokan suora kantaluokka, joten se on KauraLtk-luokan epäsuora kantaluokka. Voimme nyt kirjoittaa seuraavaa: Laatikko* pltk = pkauraltk; Tämä lause muuntaa pkauraltk:n sisältämän osoitteen tyypin tyypistä osoitin KauraLtk-olioon tyyppiin osoitin Laatikko-olioon. Jos sinun tulee määritellä muunnos eksplisiittisesti, voit käyttää static_cast()-operaattoria: Laatikko* pltk = static_cast<laatikko*>(pkauraltk); Kääntäjä pystyy yleensä suorittamaan tämän muunnoksen, koska se pystyy päättelemään, että Laatikko on KauraLtk:n kantaluokka. Koska KauraLtk-olio sisältää Laatikko-olion, muunnos on mahdollinen. Muunnos ei ole mahdollinen, jos Laatikko-luokkaan ei päästä käsiksi, tai jos Laatikko-luokka on virtuaalinen kantaluokka. Kääntäjä huomaa tällaiset tilanteet. Seuraavassa kaaviossa on kaikki mahdolliset muunnokset alkaen KauraLtk-luokasta. 640

21 Virtuaalifunktiot ja polymorfismi Muunnos suoraan kantaluokkaan: ppahviltk = ppak; KauraLtk* ppak = new KauraLtk; ppak KauraLtk-olio ppak KauraLtk-olio ppahviltk PahviLaatikko -olio PahviLaatikko -olio Laatikko- olio Laatikko- olio Muunnos epäsuoraan kantaluokkaan: pltk = ppak; ppak KauraLtk-olio Osoittimien muunnokset hierarkiassa ylöspäin pltk PahviLaatikko -olio Laatikko- olio Kuten huomaat, jokaisen tapauksen tuloksena on osoitin kohteena olevan tyypin aliolioon. On erittäin helppoa mennä sekaisin, kun pohdit osoittimen muunnoksia luokkatyyppien välillä. Muista, että osoitin tiettyyn luokkatyyppiin voi osoittaa vain kyseisen tyyppisiin olioihin tai periytetyn luokan olioihin, ei toisinpäin. Tarkasti ottaen, osoitin ppahvilaatikko voi sisältää PahviLaatikko-tyyppisen olion osoitteen (joka on KauraLtk-olion aliolio) tai KauraLtk-tyyppisen olion osoitteen. Se ei voi sisältää Laatikko-tyyppisen olion osoitetta, koska KauraLtk on eräänlainen PahviLaatikko, mutta Laatikko ei ole. Edellä kerrotusta huolimatta on joskus mahdollista tehdä muunnoksia toiseenkin suuntaan. Osoittimen muuntaminen luokkahierarkiassa alaspäin, kantaluokasta periytettyyn luokkaan, on erilainen tilanne, koska muunnos riippuu siitä, mihin kantaluokan osoitin osoittaa. Muunnos esimerkiksi kantaluokan olion osoittimesta pltk periytetyn luokan olion osoittimeen voidaan suorittaa vain, jos kantaluokan osoitin osoittaa PahviLaatikko-luokan Laatikko-aliolioon. Jos näin ei ole, muunnoksen tulos on määrittelemätön. PahviLaatikko* ppahviltk = static_cast<pahvilaatikko*>(pltk); Laatikko* pltk = new PahviLaatikko; ppahviltk PaviLaatikko-olio PaviLaatikko-olio pltk Laatikko -olio pltk Laatikko -olio KauraLtk* ppak = static_cast<kauraltk*>(pltk); PaviLaatikko-olio Osoittimien muunnokset hierarkiassa alaspäin ppak pltk Laatikko -olio??? - määrittelemätön 641

22 C++ Ohjelmoijan käsikirja Kaavio näyttää muunnoksen osoittimesta pltk, joka sisältää PahviLaatikko-olion osoitteen. Muunnos tyyppiin PahviLaatikko* toimii, koska olio on tyyppiä PahviLaatikko. Tyyppiin KauraLtk* muunnoksen tulos on kuitenkin määrittelemätön, koska sen tyyppistä oliota ei ole olemassa. Jos et ole aivan varma, että muunnos on sallittu, älä käytä sitä. Osoittimen muuntaminen hierarkiassa alaspäin onnistuu, jos osoitin sisältää kohteena olevan tyypin osoitteen. Muunnos ei tarkista, onko tämä totta, joten jos yrität käyttää muunnosta tilanteessa, jossa et ole aivan varma mihin osoitin osoittaa, voit saada määrittelemättömän tuloksen. Tästä syystä sinun tulee muuntaa luokkahierarkiassa alaspäin eri tavalla: tavalla, jolla muunnos voidaan tarkistaa suoritusaikana. Dynaaminen muunnos Dynaaminen muunnos on muunnos, joka tehdään suoritusaikana. Se suoritetaan dynamic_cast<>()-operaattorilla. Voit käyttää tätä operaattoria ainoastaan polymorfististen luokkien osoittimien ja viittausten yhteydessä - eli luokkien yhteydessä, joilla on vähintään yksi virtuaalifunktio. Tämä siitä syystä, että ainoastaan polymorfististen luokkien osoittimet sisältävät tietoa, jota dynamic_cast<>()-operaattori tarvitsee muunnoksen tarkistamiseen. Tämä operaattori on tarkoitettu muuntamaan luokkahierarkian luokkien osoittimien välillä tai luokkahierarkian luokkien viittausten välillä. Huomaa, että tyypit, joiden välillä teet muunnoksen, täytyy olla osoittimia tai viittauksia saman luokkahierarkian luokkiin. Et voi käyttää dynamic_cast<>()-operaattoria mihinkään muuhun. Aloitamme operaattorin tutkimisen osoittimien dynaamisesta tyypinmuunnoksesta. Osoittimien dynaamiset muunnokset Voimme erottaa kaksi dynaamista muunnosta. Ensimmäinen on muunnos hierarkiassa alaspäin, suoran tai epäsuoran kantaluokan osoittimesta periytetyn luokan osoittimeen. Tätä kutsutaan alasmuunnokseksi. Toinen mahdollisuus on muuntaa hierarkiassa ristiin; tätä kutsutaan ristiinmuunnokseksi. Näitä kumpaakin havainnollistetaan alla olevassa kaaviossa. class Laatikko Alasmuunnoksen esimerkki: Tyypistä osoitin Laatikko-olioon tyyppiin osoitin PahviLtk-olioon Ristiinmuunnoksen esimerkki: Tyypistä osoitin Laatikko-olioon tyyppiin osoitin Sisalto-olioon class PahviLaatikko: public Laatikko class Sisalto class KauraLtk : public PahviLaatikko, publicsisalto 642

23 Virtuaalifunktiot ja polymorfismi Osoittimelle pltk, joka on tyyppiä osoitin Laatikko-luokkaan, voimme kirjoittaa kaaviossa kuvatun alasmuunnoksen seuraavasti: PahviLaatikko* ppahviltk = dynamic_cast<pahvilaatikko*>(pltk); Kuten huomaat, dynamic_cast<>()-operaattori kirjoitetaan samaan tapaan kuin static_cast<>()- operaattorikin. Kohdetyyppi kirjoitetaan kulmasulkeiden sisään ja lauseke, jonka haluat muuntaa uuteen tyyppiin, kirjoitetaan tavallisten sulkeiden sisään. Jotta tämä muunnos on sallittu, luokilla Laatikko ja PahviLaatikko tulee olla virtuaalisia funktioita, joko omia tai perittyjä. Jotta muunnos toimii, pltk:n tulee osoittaa joko PahviLaatikko-olioon tai KauraLtk-olioon, koska vain näiden tyyppiset oliot sisältävät PahviLaatikko-aliolion. Jos muunnos ei onnistu, osoittimen ppahviltk arvoksi asetetaan 0. Kaaviossa esitetty ristiinmuunnos voidaan kirjoittaa seuraavasti: Sisalto* psisalto = dynamic_cast<sisalto*>(pltk); Kuten edellisessäkin tapauksessa, Sisalto- ja Laatikko-luokkien tulee kummankin olla polymorfistisia, jotta muunnos on sallittu. Muunnos onnistuu ainoastaan, jos pltk sisältää KauraLtk-tyyppisen olion osoitteen, koska se on ainut tyyppi, joka sisältää Sisalto-olion ja johon voidaan viitata Laatikko*-tyyppisellä osoittimella. Jälleen, jos muunnos ei onnistu, psisaltoosoittimen arvoksi asetetaan 0. Alasmuuntaminen luokkahierarkiassa dynamic_cast<>()-operaattorin avulla voi epäonnistua, mutta tällöin palautetaan null-osoitin, eikä vain määrittelemätöntä arvoa. Tämä antaakin sinulle jo vihjeen, miten tätä muunnosta tulee käyttää. Oletetaan, että sinulla on jokin olio, johon osoitetaan Laatikko*-tyyppisellä osoittimella ja haluat kutsua ei-virtuaalista PahviLaatikkoluokan jäsenmuuttujaa. Kantaluokan osoittimen avulla voit kutsua ainoastaan periytetyn luokan virtuaalifunktiota, mutta dynamic_cast<>()-operaattorin avulla voit kutsua ei-virtuaalista funktiota. Oletetaan, että pinta_ala() on ei-virtuaalinen PahviLaatikko-luokan jäsenfunktio. Voit kutsua sitä lauseella: dynamic_cast<pahvilaatikko*>(pltk)->pinta_ala(); Tämä on kuitenkin varsin vaarallista. Sinun täytyy yhä olla varma, että pltk osoittaa PahviLaatikko-olioon tai sellaisen luokan olioon, jolla on PahviLaatikko-luokka kantaluokkana. Jos näin ei ole, dynamic_cast<>()-operaattori palauttaa null-osoittimen ja kutsu epäonnistuu. Voit korjata tämän käyttämällä ennen funktion kutsua dynamic_cast<>()-operaattoria esimerkiksi seuraavasti: if(pahvilaatikko* ppahviltk = dynamic_cast<pahvilaatikko*>(pltk)) ppahviltk->pinta_ala(); Nyt kutsumme funktiota vain, jos muunnoksen tulos ei ole null. Huomaa, että et voi poistaa const-määreen vaikutusta dynamic_cast<>()-operaattorilla. Jos osoitin, josta olet muuntamassa, on const-tyyppinen, osoittimen tyyppi, joksi olet muuntamassa, tulee myöskin olla const-tyyppinen. Jos haluat muunta const-tyyppisestä osoittimesta muuhun kuin const-tyyppiseen osoittimeen, sinun tulee ensin muuntaa muunnettavaa tyyppiä olevaan muuhun kuin const-tyyppiseen osoittimeen const_cast<>()-operaattorilla. 643

Periytyminen. Luokat ja olio-ohjelmointi

Periytyminen. Luokat ja olio-ohjelmointi Periytyminen 15 Periytyminen Tässä luvussa käsittelemme aihetta, joka on olio-ohjelmoinnin kaikkein tärkein osa - periytyvyys. Periytyvyyden avulla voimme luoda uusia luokkia uudelleenkäyttämällä ja laajentamalla

Lisätiedot

Luokat. Luokat ja olio-ohjelmointi

Luokat. Luokat ja olio-ohjelmointi Luokat 12 Luokat Tässä luvussa laajennamme edellisessä luvussa käsittelemäämme struktuurityyppiä ja siirrymme yhteen C++-ohjelmoijan kaikkein tärkeimmistä välineistä: luokkiin. Käsittelemme myöskin joitakin

Lisätiedot

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 12. Periytyminen Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi

Lisätiedot

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

Lisätiedot

Ohjelman virheet ja poikkeusten käsittely

Ohjelman virheet ja poikkeusten käsittely Ohjelman virheet ja poikkeusten käsittely 17 Ohjelman virheet ja poikkeusten käsittely Poikkeukset ovat tapa ilmoittaa virheistä ja odottamattomista tilanteista C++-ohjelmassasi. Poikkeusten käyttö virheiden

Lisätiedot

Operaattoreiden uudelleenmäärittely

Operaattoreiden uudelleenmäärittely Operaattoreiden uudelleenmäärittely 14 Operaattoreiden uudelleenmäärittely Tässä luvussa käsittelemme, kuinka voit lisätä toiminnallisuutta luokkiisi, jotta ne toimivat enemmän C++:n perustietotyyppien

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 3 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten muuttujiin liittyvät kysymykset. Tehtävä 1. Määritä muuttujien max_num, lista,

Lisätiedot

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta C++ - perusteet Java-osaajille luento 5/7: operaattoreiden ylikuormitus, oliotaulukko, parametrien oletusarvot, komentoriviparametrit, constant, inline, Operaattoreiden ylikuormitus Operaattoreiden kuormitus

Lisätiedot

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi 1 C++11 Syntaksi Jari-Pekka Voutilainen 13.4.2012 2 Range-for Iteroi säiliön kaikki alkiot for-silmukassa. Säiliöltä vaaditaan begin- ja end-iteraattorit. Pätee kaikille C++11 STL-säiliöille, taulukoille,

Lisätiedot

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat: 1. Luokan jäsenet Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat: class luokan_nimi tyypit: enum, struct, class, typedef

Lisätiedot

Mallit standardi mallikirjasto parametroitu tyyppi

Mallit standardi mallikirjasto parametroitu tyyppi Mallit 18 Mallit Malli on tehokas mekanismi uusien luokkien generoimiseksi automaattisesti. Standardikirjaston suuri osa, standardi mallikirjasto, rakentuu kokonaan mallien määrittelymahdollisuuden ympärille,

Lisätiedot

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin Luokan operaatiot 13 Luokan operaatiot Luokkien olioiden luomiseen ja tuhoamiseen liittyy monia hienouksia, joista sinun tulee olla selvillä, jotta luokkiesi olioiden operaatiot toimivat turvallisesti

Lisätiedot

12 Mallit (Templates)

12 Mallit (Templates) 12 Mallit (Templates) Malli on määrittely, jota käyttämällä voidaan luoda samankaltaisten aliohjelmien ja luokkien perheitä. Malli on ohje kääntäjälle luoda geneerisestä tyyppiriippumattomasta ohjelmakoodista

Lisätiedot

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Kirjoita jokaiseen palauttamaasi konseptiin kurssin nimi, kokeen päivämäärä, oma nimi ja opiskelijanumero. Vastaa kaikkiin tehtäviin omille konsepteilleen.

Lisätiedot

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: Harjoitus 7 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: class Lintu //Kentät private int _siivenpituus; protected double _aivojenkoko; private bool _osaakolentaa; //Ominaisuudet public int

Lisätiedot

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Liite E - Esimerkkiprojekti E Esimerkkiprojekti Olet lukenut koko kirjan. Olet sulattanut kaiken tekstin, Nyt on aika soveltaa oppimiasi uusia asioita pienen, mutta täydellisesti muotoiltuun, projektiin.

Lisätiedot

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia. 4. Periytyminen 4.1. Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi

Lisätiedot

Taulukot. Jukka Harju, Jukka Juslin 2006 1

Taulukot. Jukka Harju, Jukka Juslin 2006 1 Taulukot Jukka Harju, Jukka Juslin 2006 1 Taulukot Taulukot ovat olioita, jotka auttavat organisoimaan suuria määriä tietoa. Käsittelylistalla on: Taulukon tekeminen ja käyttö Rajojen tarkastus ja kapasiteetti

Lisätiedot

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 11. Luokka Opetellaan seuraavaksi, miten omia luokkia kirjoitetaan. Aikaisemmin olikin jo esillä, että luokka on tietorakenne, joka sisältää sekä tiedot (attribuutit) että niitä käsittelevät aliohjelmat

Lisätiedot

12. Monimuotoisuus 12.1

12. Monimuotoisuus 12.1 12. Monimuotoisuus 12.1 Sisällys Johdanto. Periytymismekanismi määrittää alityypityksen. Viitteiden sijoitus ja vertailu. Staattinen ja dynaaminen luokka. Myöhäinen ja aikainen sidonta. Parametrinvälitys

Lisätiedot

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä 812347A Olio-ohjelmointi, 2015 syksy 2. vsk X Poikkeusten käsittelystä Sisältö 1. Yleistä poikkeusten käsittelystä 2. Poikkeuskäsittelyn perusteita C++:ssa 3. Standardissa määritellyt poikkeukset 4. Poikkeusvarmuus

Lisätiedot

Omat tietotyypit. Mikä on olio?

Omat tietotyypit. Mikä on olio? Omat tietotyypit 11 Omat tietotyypit C++:n suuri vahvuus on sen oliopohjaisuudessa. Siihen liittyy runsaasti asiaa ja kulutammekin seuraavat viisi lukua tässä aiheessa. Tässä ja seuraavassa luvussa käsittelemme

Lisätiedot

12. Monimuotoisuus 12.1

12. Monimuotoisuus 12.1 12. Monimuotoisuus 12.1 Sisällys Johdanto. Periytymismekanismi määrittää alityypityksen. Viitteiden sijoitus ja vertailu. Staattinen ja dynaaminen luokka. Parametrinvälitys eräs monimuotoisuuden sovellus.

Lisätiedot

9. Periytyminen Javassa 9.1

9. Periytyminen Javassa 9.1 9. Periytyminen Javassa 9.1 Sisällys Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Ilmentymämetodien korvaaminen. Luokkametodien peittäminen. Super-attribuutti. Override-annotaatio.

Lisätiedot

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen Metodit Metodien määrittely Metodin parametrit ja paluuarvo Metodien suorittaminen eli kutsuminen Metodien kuormittaminen 1 Mikä on metodi? Metodi on luokan sisällä oleva yhteenkuuluvien toimintojen kokonaisuus

Lisätiedot

Geneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö.

Geneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö. Geneeriset luokat C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet Geneerinen luokka tarkoittaa parametroitua luokkamallia, jonka avulla voidaan muodostaa useita,

Lisätiedot

13 Operaattoreiden ylimäärittelyjä

13 Operaattoreiden ylimäärittelyjä 248 13 C++-kielessä voidaan operaattoreita ylimäärittää. Ylimääriteltävää operaattoria voidaan pitää ikäänkuin metodina, joka esitellään luokan esittelyssä ja määritellään luokan ulkopuolella kuten metoditkin.

Lisätiedot

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu: TL5302 Olio-ohjelmointi Koe 19.4.2005 Malliratkaisuja Tehtävä 1 Tässä sekä a)- että b)-kohdan toimiva ratkaisu: #include using namespace std; int main() int taul[5]=1,2,3,4,5; int *p,&r=taul[0];

Lisätiedot

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4) 2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi

Lisätiedot

Olio-ohjelmointi Javalla

Olio-ohjelmointi Javalla 1 Olio-ohjelmointi Javalla Olio-ohjelmointi Luokka Attribuutit Konstruktori Olion luominen Metodit Olion kopiointi Staattinen attribuutti ja metodi Yksinkertainen ohjelmaluokka Ohjelmaluokka 1 Olio-ohjelmointi

Lisätiedot

Kääntäjän virheilmoituksia

Kääntäjän virheilmoituksia OHJ-1101 Ohjelmointi 1e 2008-09 1 Kääntäjän virheilmoituksia Kun progvh2 ohjelma käännetään antaa tutg++ seuraavat virheilmoitukset ja varoitukset: proffa> tutg++ progvh2.cc progvh2.cc:29:13: warning:

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 20. huhtikuuta 2018 Vastaa kaikkiin tehtäviin. Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä.

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Lueteltu tyyppi enum. Override-annotaatio. Geneerinen ohjelmointi. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien

Lisätiedot

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2 6. Metodit 6.1 Sisällys Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2 Oliot viestivät metodeja kutsuen Olio-ohjelmoinnissa ohjelma

Lisätiedot

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä Matti Luukkainen 10.12.2009 Tässä esitetty esimerkki on mukaelma ja lyhennelmä Robert Martinin kirjasta Agile and Iterative Development löytyvästä

Lisätiedot

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus? Osa III 11. oppitunti Viittaukset Kahdessa viime luvussa opit käyttämään osoittimia kohteiden käsittelyyn vapaalla muistialueella sekä viittaamaan noihin kohteisiin epäsuorasti. Tässä luvussa käsiteltävät

Lisätiedot

Osa III. Olioiden luominen vapaalle muistialueelle

Osa III. Olioiden luominen vapaalle muistialueelle Osa III 10. oppitunti Kehittyneet osoittimet Eräs tehokkaimpia C++ -työkaluja on mahdollisuus käsitellä tietokoneen muistia suoraan osoittimien avulla. Tässä luvussa käsitelläänkin seuraavia aiheita: Kuinka

Lisätiedot

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa(); Sisällys 7. Oliot ja viitteet Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden käsittelyä: sijoitus, vertailu ja varautuminen null-arvoon. Viite metodin paluuarvona.. 7.1 7.2 Olio

Lisätiedot

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance) Sisällys JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys Periytyminen (inheritance) Näkyvyys (visibility) Eero Hyvönen Tietojenkäsittelytieteen laitos Helsingin yliopisto 13.10.2000 E. Hyvönen: Java Osa

Lisätiedot

4. Luokan testaus ja käyttö olion kautta 4.1

4. Luokan testaus ja käyttö olion kautta 4.1 4. Luokan testaus ja käyttö olion kautta 4.1 Olion luominen luokasta Java-kielessä olio määritellään joko luokan edustajaksi tai taulukoksi. Olio on joukko keskusmuistissa olevia tietoja. Oliota käsitellään

Lisätiedot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan

Lisätiedot

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukot C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukon muuttujilla (muistipaikoilla) on yhteinen nimi. Jokaiseen yksittäiseen

Lisätiedot

Osoittimet. Mikä on osoitin?

Osoittimet. Mikä on osoitin? Osoittimet 7 Osoittimet On aika siirtyä käsittelemään osoittimia, C++:lle elintärkeätä ominaisuutta. Osoittimet ovat tärkeitä, koska ne luovat perustan muistin dynaamiselle varaukselle ja käytölle. Ne

Lisätiedot

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista Sisällys 1. Omat operaatiot Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print

Lisätiedot

Osa III. Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat:

Osa III. Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat: Osa III 12. oppitunti Kehittyneet viittaukset ja osoittimet Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat: Kuinka viittausten viemisellä voidaan tehostaa

Lisätiedot

1. Omat operaatiot 1.1

1. Omat operaatiot 1.1 1. Omat operaatiot 1.1 Sisällys Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Olio-ohjelmointi Syntaksikokoelma

Olio-ohjelmointi Syntaksikokoelma C++-kielen uusia ominaisuuksia Olio-ohjelmointi Syntaksikokoelma 31.10.2008 Bool-tietotyyppi: Totuusarvo true (1), jos ehto on tosi ja false (0) jos ehto epätosi. Dynaaminen muistinvaraus: Yhden muuttuja

Lisätiedot

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Taulukot: Array Taulukko Javassa pitää aina perustaa (new) Yksinkertaisessa tilanteessa taulukon koko tiedetään etukäteen ja

Lisätiedot

Tutoriaaliläsnäoloista

Tutoriaaliläsnäoloista Tutoriaaliläsnäoloista Tutoriaaliläsnäolokierroksella voi nyt täyttää anomuksen läsnäolon merkitsemisestä Esim. tagi ei toiminut, korvavaltimon leikkaus, yms. Hyväksyn näitä omaa harkintaa käyttäen Tarkoitus

Lisätiedot

Rajapinta (interface)

Rajapinta (interface) 1 Rajapinta (interface) Mikä rajapinta on? Rajapinta ja siitä toteutettu luokka Monimuotoisuus ja dynaaminen sidonta Rajapinta vs periytyminen 1 Mikä rajapinta on? Rajapintoja käytetään, kun halutaan määritellä

Lisätiedot

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout: C++ rautaisannos Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout: # include #include main ( ) main (

Lisätiedot

Olio-ohjelmointi 2. välikoe HYV5SN

Olio-ohjelmointi 2. välikoe HYV5SN Olio-ohjelmointi 2. välikoe 27.4.2007 HYV5SN 1. Tee ohjelma, joka sisältää laatikko-luokan. Luokan tietojäseninä ovat laatikon syvyys, leveys ja korkeus. Toteuta luokkaan muodostin, jonka avulla olio voidaan

Lisätiedot

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä Rekursiolause Laskennan teorian opintopiiri Sebastian Björkqvist 23. helmikuuta 2014 Tiivistelmä Työssä käydään läpi itsereplikoituvien ohjelmien toimintaa sekä esitetään ja todistetaan rekursiolause,

Lisätiedot

Java kahdessa tunnissa. Jyry Suvilehto

Java kahdessa tunnissa. Jyry Suvilehto Java kahdessa tunnissa Jyry Suvilehto Ohjelma Ohjelmointiasioita alkeista nippelitietoon n. 45 min Tauko 10 min Oliot, luokat ja muut kummajaiset n. 45 min Kysykää Sisältöä ei oikeasti ole 2x45 min täytteeksi,

Lisätiedot

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU Ohjelmointi 2 Jussi Pohjolainen TAMK» Tieto- ja viestintäteknologia Tietotyypeistä C++ - kielessä useita tietotyyppejä Kirjaimet: char, wchar_t Kokonaisluvut: short, int, long Liukuluvut: float, double

Lisätiedot

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19 Ohjelmointikieli TIE-20306 Principles of Programming Languages Syksy 2017 Ryhmä 19 Juho Kärnä Ville Mäntysaari 1. Johdanto D on yleiskäyttöinen, strukturoitu, staattisesti tyypitetty, käännettävä ohjelmointikieli

Lisätiedot

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä LUOKAN MÄÄRITTELY Luokka, mitä se sisältää Luokan määrittely Olion ominaisuudet eli attribuutit Olion metodit Olion muodostimet ja luonti Olion tuhoutuminen Metodin kutsu luokan ulkopuolelta Olion kopioiminen

Lisätiedot

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä Sisällys 9. Periytyminen Javassa Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Metodien korvaaminen ja super-attribuutti. Attribuutin peittäminen periytymisen kautta. Rakentajat

Lisätiedot

Aalto Yliopisto T-106.2001 Informaatioverkostot: Studio 1. Oliot ja luokat Javaohjelmoinnissa

Aalto Yliopisto T-106.2001 Informaatioverkostot: Studio 1. Oliot ja luokat Javaohjelmoinnissa Aalto Yliopisto T-106.2001 Informaatioverkostot: Studio 1 Oliot ja luokat Javaohjelmoinnissa Vesa Laakso 22.9.2012 Sisällysluettelo Sisällysluettelo... 1 Johdanto... 2 1. Luokka... 2 2. Olio... 2 3. Luokan

Lisätiedot

9. Periytyminen Javassa 9.1

9. Periytyminen Javassa 9.1 9. Periytyminen Javassa 9.1 Sisällys Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Metodien korvaaminen ja super-attribuutti. Attribuutin peittäminen periytymisen kautta. Rakentajat

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Geneerinen ohjelmointi. Lueteltu tyyppi enum. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien silmukoimiseen:

Lisätiedot

Solidity älysopimus ohjelmointi. Sopimus suuntautunut ohjelmointi

Solidity älysopimus ohjelmointi. Sopimus suuntautunut ohjelmointi Solidity älysopimus ohjelmointi Sopimus suuntautunut ohjelmointi Merkle puu Kertausta eiliseltä Solidity on korkean tason älysopimus ohjelmointikieli Muistuttaa olio-ohjelmointia Javalla Sopimuskoodi on

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä Sisällys 9. Periytyminen Javassa Periytymismekanismi Java-kielessä. Piirteiden näkyvyys periytymisessä. Metodien korvaaminen ja super-attribuutti. Attribuutin peittäminen periytymisen kautta. Rakentajat

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 12. huhtikuuta 2019 Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä. Yksi A4-kokoinen lunttilappu

Lisätiedot

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen Sisällys 6. Metodit Oliot viestivät metodeja kutsuen. Kuormittaminen. Luokkametodit (ja -attribuutit).. Metodien ja muun luokan sisällön järjestäminen. 6.1 6.2 Oliot viestivät metodeja kutsuen Oliot viestivät

Lisätiedot

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2 4. Attribuutit 4.1 Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2 Yleistä Luokan lohkossa, mutta metodien ulkopuolella esiteltyjä

Lisätiedot

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2 4. Attribuutit 4.1 Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2 Yleistä Luokan lohkossa, mutta metodien ulkopuolella esiteltyjä muuttujia ja vakioita. Esittely

Lisätiedot

Metodien tekeminen Javalla

Metodien tekeminen Javalla 1 Metodien tekeminen Javalla Mikä metodi on? Metodin syntaksi Metodi ja sen kutsuminen Parametreista Merkkijonot ja metodi Taulukot ja metodi 1 Mikä metodi on? Metodilla toteutetaan luokkaan toiminnallisuutta.

Lisätiedot

C# olio-ohjelmointi perusopas

C# olio-ohjelmointi perusopas Paavo Räisänen C# olio-ohjelmointi perusopas www.ohjelmoimaan.net Tätä opasta saa vapaasti kopioida, tulostaa ja levittää ei kaupallisissa tarkoituksissa. Kuitenkaan omille nettisivuille opasta ei saa

Lisätiedot

1 Tehtävän kuvaus ja analysointi

1 Tehtävän kuvaus ja analysointi Olio-ohjelmoinnin harjoitustyön dokumentti Jyri Lehtonen (72039) Taneli Tuovinen (67160) 1 Tehtävän kuvaus ja analysointi 1.1 Tehtävänanto Tee luokka, jolla mallinnetaan sarjaan kytkettyjä kondensaattoreita.

Lisätiedot

Ohjelmoinnin perusteet, kurssikoe

Ohjelmoinnin perusteet, kurssikoe Ohjelmoinnin perusteet, kurssikoe 18.6.2014 Kirjoita jokaiseen konseptiin kurssin nimi, kokeen päivämäärä, nimi, TMC-tunnus ja opiskelijanumero tai henkilötunnus. Vastaukset palautetaan tehtäväkohtaisiin

Lisätiedot

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: {

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: { Osa I 2. oppitunti C++-ohjelman osat Ennen kuin menemme yksityiskohtaisemmin sisälle C++-luokkiin, -muuttujiin jne, katsokaamme ensin, millaisista osista C++-ohjelma koostuu. Tämän tunnin aikana opit seuraavat

Lisätiedot

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys) 1(37) PERIYTYMINEN (inheritance) YLILUOKKA (superclass) ALILUOKKA (subclass) A) on käytännöllinen ohjelmointitekniikka = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys) B) on käsitteiden

Lisätiedot

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5) Alkuarvot ja tyyppimuunnokset (1/5) Aiemmin olemme jo antaneet muuttujille alkuarvoja, esimerkiksi: int luku = 123; Alkuarvon on oltava muuttujan tietotyypin mukainen, esimerkiksi int-muuttujilla kokonaisluku,

Lisätiedot

C++11 lambdat: [](){} Matti Rintala

C++11 lambdat: [](){} Matti Rintala C++11 lambdat: [](){} Matti Rintala bool(*)(int) Tarve Tarve välittää kirjastolle/funktiolle toiminnallisuutta Callback-funktiot Virhekäsittely Käyttöliittymät Geneeristen kirjastojen räätälöinti STL:n

Lisätiedot

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++? JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: http://java.sun.com/docs/books/tutorial/index.html Vesterholm, Kyppö: Java-ohjelmointi,

Lisätiedot

Ohjelmointi 1 Taulukot ja merkkijonot

Ohjelmointi 1 Taulukot ja merkkijonot Ohjelmointi 1 Taulukot ja merkkijonot Jussi Pohjolainen TAMK Tieto- ja viestintäteknologia Johdanto taulukkoon Jos ohjelmassa käytössä ainoastaan perinteisiä (yksinkertaisia) muuttujia, ohjelmien teko

Lisätiedot

815338A Ohjelmointikielten periaatteet

815338A Ohjelmointikielten periaatteet 815338A Ohjelmointikielten periaatteet 2015-2016 V Abstraktit tietotyypit ja olioohjelmointi Sisältö I. Abstraktit tietotyypit II. 1. Johdatus abstrakteihin tietotyyppeihin 2. Abstraktit tietotyypit Adassa

Lisätiedot

Ohjelmointi funktioiden avulla

Ohjelmointi funktioiden avulla Ohjelmointi funktioiden avulla 8 Ohjelmointi funktioiden avulla Ohjelman jakaminen hallittaviin osiin on idea, joka on perustana kaikille ohjelmointikielille. Funktio on kaikkien C++-ohjelmien perusosa.

Lisätiedot

TIE-20200 Ohjelmistojen suunnittelu

TIE-20200 Ohjelmistojen suunnittelu TIE-20200 Ohjelmistojen suunnittelu Luento 1: Virtuaalifunktiot, Template method 1 Yleistä asiaa Muistakaa harkkatyöilmoittautuminen 23 ryhmää (mm. lihansyöjäkirahvi), vajaita ryhmiäkin on 44 henkeä vielä

Lisätiedot

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia.

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia. Ohjelmointitaito (ict1td002, 12 op) Kevät 2008 Raine Kauppinen raine.kauppinen@haaga-helia.fi 1. Java-ohjelmoinnin alkeita Tietokoneohjelma Java-kieli ja Eclipse-ympäristö Java-ohjelma ja ohjelmaluokka

Lisätiedot

TIE-20200 Ohjelmistojen suunnittelu

TIE-20200 Ohjelmistojen suunnittelu TIE-20200 Ohjelmistojen suunnittelu Luento 1: Virtuaalifunktiot, Template method 1 Seuraavaksi tarjolla: Otekn-asiaa vähän pintaa syvemmältä Virtuaalifunktiot ja erikoistaminen, olioiden kopiointi ja elinaika

Lisätiedot

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin Raimo Nikkilä Aalto-yliopiston sähkötekniikan korkeakoulu - Automaation tietotekniikan tutkimusryhmä 17. tammikuuta 2013

Lisätiedot

2. Olio-ohjelmoinista lyhyesti 2.1

2. Olio-ohjelmoinista lyhyesti 2.1 2. Olio-ohjelmoinista lyhyesti 2.1 Sisällys Yleistä. Oliot ja luokat. Attribuutit. Olioiden esittely ja alustus. Rakentajat. Olion operaation kutsuminen. 2.2 Yleistä Olio-ohjelmointia käsitellään hyvin

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

Tässä tehtävässä käsittelet metodeja, listoja sekä alkulukuja (englanniksi prime ).

Tässä tehtävässä käsittelet metodeja, listoja sekä alkulukuja (englanniksi prime ). Tehtävä 1: Metodit, listat, alkuluvut (4p) Tässä tehtävässä käsittelet metodeja, listoja sekä alkulukuja (englanniksi prime ). Alkuluvut ovat lukuja, jotka ovat suurempia kuin yksi ja jotka ovat jaollisia

Lisätiedot

7. Oliot ja viitteet 7.1

7. Oliot ja viitteet 7.1 7. Oliot ja viitteet 7.1 Sisällys Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden sijoitus. Viitteiden vertailu. Varautuminen null-arvoon. Viite metodin paluuarvona. Viite metodin

Lisätiedot

Ohjelmointi 2 / 2010 Välikoe / 26.3

Ohjelmointi 2 / 2010 Välikoe / 26.3 Ohjelmointi 2 / 2010 Välikoe / 26.3 Välikoe / 26.3 Vastaa neljään (4) tehtävään ja halutessa bonustehtäviin B1 ja/tai B2, (tuovat lisäpisteitä). Bonustehtävät saa tehdä vaikkei olisi tehnyt siihen tehtävään

Lisätiedot

Loppukurssin järjestelyt

Loppukurssin järjestelyt C! Loppukurssin järjestelyt 29.3.2018 Ohjelmassa Yhteenvetoa palautteesta Ohjelmontitehtävän järjestelyt Tietokonetentin järjestelyt Kysyttävää / kerrattavaa 10-kierroksen asioista? Aikatauluista 10. kierroksen

Lisätiedot

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä Sisälls 7. Oliot ja viitteet Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen.. Viitteiden vertailu. Varautuminen null-arvoon. Viite metodin paluuarvona.. Muuttumattomat ja muuttuvat merkkijonot.

Lisätiedot

Oliot viestivät metodeja kutsuen

Oliot viestivät metodeja kutsuen 6. Metodit 6.1 Sisällys Oliot viestivät metodeja kutsuen. Kuormittaminen. Luokkametodit (ja -attribuutit). Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2 Oliot viestivät metodeja kutsuen

Lisätiedot

1. Miten tehdään peliin toinen maila?

1. Miten tehdään peliin toinen maila? Muilla kielillä: English Suomi Pong-peli, vaihe 4 Tässä oppaassa teemme toisenkin mailan. 1. Miten tehdään peliin toinen maila? Maila tehtiin edellisessä vaiheessa, aliohjelmassa LuoKentta, seuraavasti:

Lisätiedot

Ohjelmoinnin perusteet, syksy 2006

Ohjelmoinnin perusteet, syksy 2006 Ohjelmoinnin perusteet, syksy 2006 Esimerkkivastaukset 1. harjoituksiin. Alkuperäiset esimerkkivastaukset laati Jari Suominen. Vastauksia muokkasi Jukka Stenlund. 1. Esitä seuraavan algoritmin tila jokaisen

Lisätiedot

Loppukurssin järjestelyt C:n edistyneet piirteet

Loppukurssin järjestelyt C:n edistyneet piirteet C! Loppukurssin järjestelyt C:n edistyneet piirteet 30.3.2017 Ohjelmassa Ohjelmontitehtävän järjestelyt Tietokonetentin järjestelyt Esikääntäjä Parametrilistat Funktio-osoittimet Kunniamainintoja Kuura

Lisätiedot

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti: 1 (7) Tiedon lukeminen näppäimistöltä Scanner-luokan avulla Miten ohjelma saa käyttöönsä käyttäjän kirjoittamaa tekstiä? Järjestelmässä on olemassa ns. syöttöpuskuri näppäimistöä varten. Syöttöpuskuri

Lisätiedot

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot