Mallit standardi mallikirjasto parametroitu tyyppi

Koko: px
Aloita esitys sivulta:

Download "Mallit standardi mallikirjasto parametroitu tyyppi"

Transkriptio

1 Mallit 18 Mallit Malli on tehokas mekanismi uusien luokkien generoimiseksi automaattisesti. Standardikirjaston suuri osa, standardi mallikirjasto, rakentuu kokonaan mallien määrittelymahdollisuuden ympärille, joten malleihin liittyvät tekniikat ovat tärkeitä. Tämän luvun lopussa olemme käsitelleet seuraavat aiheet: Mikä on malliluokka ja miten sellainen määritellään Mikä on mallin ilmentymä ja miten sellainen luodaan Miten mallin jäsenfunktioille määritellään mallifunktio mallin määrittelyn rungon ulkopuolella Miten tyyppiparametri eroaa ei-tyyppiparametristä Miten mallin staattiset jäsenet alustetaan Mikä on osittain erikoistunut funktio ja miten sellainen määritellään Miten malli sijoitetaan toisen mallin sisälle Malliluokka Malliluokat (malli) perustuvat samaan ideaan kuin mallifunktiot, joita käsittelimme luvussa 9. Malli on parametroitu tyyppi - eli resepti, jonka mukaan luodaan luokkia käyttämällä yhtä tai useampaa parametriä, jotka ovat yleensä tyyppejä (mutta eivät aina). Kun esittelet muuttujan käyttämällä mallia, kääntäjä muodostaa mallin mukaan luokan määrittelyn käyttämiesi malliparametrien mukaan. Mallia voidaan käyttää tällä tavalla vaikka kuinka monen erilaisen luokan muodostamiseen. 707

2 C++ Ohjelmoijan käsikirja Malliluokka Tyyppiä T oleva oliotaulukko Joka kerta, kun mallille välitetään uudentyyppiset parametrit, luodaan uusi luokan määrittely. Luokan määrittely Tyyppiä int olevat oliotaulukot. Luokan määrittely Tyyppiä string olevat oliotaulukot. Luokan määrittely Tyyppiä Laatikko* olevat oliotaulukot. Nämä luokat ovat malliluokan ilmentymiä. Mallilla on nimi, aivan samaan tapaan kuin tavallisellakin luokalla, ja joukko parametrejä. Mallin nimen täytyy olla nimiavaruudessa yksikäsitteinen, joten toisella mallilla tai luokalla ei voi olla samaa nimeä kyseisessä nimiavaruudessa. Luokan määrittely muodostetaan mallista välittämällä malliparametreille tiedot. Jokaista luokkaa, jonka kääntäjä on mallista muodostanut, kutsutaan mallin ilmentymäksi. Kuten huomaat, muuttujan esittely mallin avulla luo mallin ilmentymän, mutta voit myös eksplisiittisesti esitellä mallin ilmentymän ilman, että samalla esiteltäisiin muuttuja. Mallista muodostettuja luokkia ei monisteta, eli kun tietty mallin ilmentymä on kertaalleen muodostettu, sitä käytetään mahdollisissa myöhemmissä samantyyppisten muuttujien esittelyissä. 708 Mallien käyttökohteet Vaikka malleilla on monia käyttökohteita, niiden ehkä kaikkein tärkein käyttökohde on säiliöluokkien määrittely. Säiliöluokka on luokka, joka voi sisältää tietyn tyyppisten olioiden joukon, joka on järjestetty tietyllä tavalla. Se voi olla yksinkertaisesti taulukko, pino tai olioiden linkitetty lista; idea on siinä, että käytettävä talletusmuoto ei ole riippuvainen talletettavien olioiden tyypistä. Malliluokka sisältää juuri tarvittavat apuvälineet minkä tahansa tyypin tallettavan säiliön määrittelylle. Malliparametriä voidaan käyttää määrittelemään oliotyypit, jotka säiliö tallettaa. Standardin C++:n mukana tuleva standardi mallikirjasto sisältää useita malleja, jotka määrittelevät erilaisia säiliöitä. Käsittelemme niiden käyttöä luvussa 20. Tarkastellaan yhtä tilannetta, jossa malli on hyödyllinen. Oletetaan, että olet tyytymätön siihen, että C++:n taulukot eivät tarkista, onko indeksin arvo sallittu. Tällöinhän voit vahingossa kirjoittaa muistiin taulukon rajojen yli. Yhtenä ratkaisutapana olisi tietysti kirjoittaa oma Taulukko-luokka, joka tarkistaisi, että indeksin arvo on sallittu. Kaikki mitä tarvitsisi tehdä, olisi

3 määritellä luokalle operator[]()-funktio, joka tarkistaisi indeksin arvon ja esimerkiksi muodostaisi poikkeuksen, jos indeksi ei olisi sallittu. Mutta minkä tyyppinen Taulukko-luokan tulisi olla? Yhdessä tilanteessa tarvitsisit doubletyyppistä taulukkoa ja toisessa tilanteessa tarvitsisit string-tyyppisten olioiden taulukkoa - tai itse asiassa minkä tahansa tyyppistä taulukkoa. Sinulla tulisi olla erilliset luokat jokaiselle tyypille, vaikka luokat muuten olisivat varsin samanlaiset. Useiden varsin samanlaisten luokkien kirjoittaminen kuulostaa varsin tylsältä ja tarpeettomalta - ja niinhän se onkin! Tämän lisäksi jokaisella luokalla tulisi olla oma nimi, joten lopulta sinulla saattaisi olla esimerkiksi luokat DoubleTaulukko, StringTaulukko, LaatikkoTaulukko jne. Malli pelastaa nyt meidät, koska sitä voidaan käyttää muodostamaan Taulukko-luokka, joka sopii kaikille tarvitsemillesi tyypeille. Kun olet määritellyt Taulukko-mallin, uudentyyppiset Taulukkoluokat muodostetaan varsin automaattisesti. Mallit Mallien määrittely Kun ensimmäisen kerran näet mallin määrittelyn, se näyttää monimutkaisemmalta kuin se oikeastaan on, johtuen lähinnä määrittelyssä käytetystä merkintätavasta ja koska parametrit on ripoteltu ympäri määrittelyä. Mallien määrittelyt ovat varsin samanlaiset kuin tavallistenkin luokkien määrittelyt, mutta niin kuin useiden muidenkin asioiden kohdalla, yksityiskohdat ratkaisevat. Malli määritellään avainsanan template avulla ja malliparametrit sijoitetaan template-avainsanan perässä oleviin hakasulkeisiin. Tämän jälkeen kirjoitetaan luokan määrittely alkaen classavainsanalla, jonka perään kirjoitetaan luokan nimi ja määrittelyn runko aaltosulkeiden sisään. Aivan samaan tapaan kuin tavallistenkin luokkien kohdalla, koko määrittely päättyy puolipisteeseen. Eli mallin määrittelyn yleinen muoto on: template <malliparametrien lista> class LuokanNimi // Mallin määrittely... ; Tässä käsitteellisessä määrittelyssä, LuokanNimi on mallin nimi. Mallin rungon koodi kirjoitetaan muuten aivan samaan tapaan kuin tavallisen luokankin runko, mutta joidenkin jäsenten esittelyt ja määrittelyt on tehty malliparametrien pohjalta. Malliparametrit sijaitsevat kulmasulkeiden sisällä pilkuilla eroteltuina. Kun luot luokan tästä mallista, listan jokainen parametri tulee määritellä. Malliparametrit Malliparametrien lista voi sisältää kahdenlaisia parametrejä - tyyppiparametrejä ja eityyppiparametrejä - ja listassa voi olla niin monta parametriä kuin tarvitaan. Tyyppiparametrin arvona on tyyppi, kuten int, string tai Laatikko. Ei-tyyppiparametrin arvo on joko tietyn tyyppinen arvo, kuten 200, tai tietyn tyyppinen muuttuja, kuten iarvo. Tyyppiparametrit ovat huomattavasti yleisempiä kuin ei-tyyppiparametrit, joten emme käsittele ei-tyyppiparametrejä kuin vasta luvun lopussa. 709

4 C++ Ohjelmoijan käsikirja Tyyppiparametri Ei-tyyppiparametri Taulukko-mallilla on yksi tyyppiparametri T. Tunnistat sen tyyppiparametriksi, koska sen edessä on avainsana typename. Se tyyppi, joka tälle parametrille välitetään mallin käytön yhteydessä - int, double*, string jne - määrää luokan olioon talletettavien alkioiden tyypin. Mallin rungon määrittely on varsin samanlainen kuin luokan määrittelynkin. Jäsenmuuttujat voidaan esitellä julkisiksi, suojatuiksi tai yksityisiksi ja mallilla on tyypillisesti muodostinfunktio ja tuhoajatemplate<class T, Tyyppi par,... >class LuokanNimi... ; Voit käyttää tässä typename- avainsanaa class- avainsanan sijaan. Parametri voi olla mikä tahansa tyyppi. Esimerkiksi int, double*, Laatikko&, string** jne. Parametri voi olla mikä tahansa tyypin Tyyppi arvo. Jos Tyyppi on int, parametri voi olla esimerkiksi 20 tai 100. Tyyppi voi olla ainoastaan kokonaisluku tai lueteltu tyyppi, osoitin tai viittaus olioon tai funktioon tai osoitin luokan jäseneen. Tyyppiparametrit kirjoitetaan yleensä käyttämällä class-avainsanaa, jonka perässä on parametrin nimi (class T yllä olevassa kaaviossa), mutta voit yhtä hyvin käyttää typenameavainsanaa class-avainsanan sijaan. Eli typename T kävisi yhtä hyvin. Tyyppiparametrinä käytetään usein merkkiä T (tai T1, T2 ja niin edelleen, jos mallilla on useita tyyppiparametrejä), mutta voit käyttää mitä nimeä tahansa. Vaikka class-avainsana näyttääkin viittaavan siihen, että tyyppiparametrin arvon tulee olla luokka, voit välittää minkä tahansa tyypin. Eli voit käyttää typenameavainsanaa, jos se näyttää tässä yhteydessä selkeämmältä. Katsotaan nyt miten mallit toimivat käytännössä. Näemme, miten yksinkertainen malli, jolla on yksi malliparametri, toimii käytännössä. Yksinkertainen malli Käytetään edellä ollutta esimerkkiä ja määritellään malli taulukoille, jotka tarkistavat indeksien arvot. Taulukko-mallimme sisältää ainoastaan yhden tyyppiparametrin, joten määrittelyn hahmotelma on seuraava: template <typename T> class Taulukko // Mallin määrittely... ; 710

5 funktio. Voit käyttää T:tä muuttujien esittelyissä, jäsenfunktion parametrien ja paluuarvojen tyyppinä - joko sellaisenaan tai muodossa T* (osoitin tyyppiin T). Lisäksi voit käyttää mallin nimeä - tässä tapauksessa Taulukko - tyypin nimenä muodostinfunktion ja tuhoajafunktion esittelyssä. Tarvitsemme malliin vielä muodostinfunktion, kopiomuodostimen (koska tulemme varaamaan taulukon tarvitseman muistin dynaamisesti), kopioivan sijoitusoperaattorin (koska kääntäjä muodostaa sellaisen, jos emme sitä itse tee), uudelleenmääritellyn indeksointioperaattorin ja tuhoajafunktion. Nyt voimme kirjoittaa mallin alkuperäisen määrittelyn muotoon: template <typename T> class Taulukko private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä public: explicit Taulukko<T>(size_t taulkoko); // Muodostinfunktio Taulukko<T>(const Taulukko<T>& ataul); // Kopiomuodostin ~Taulukko<T>(); // Tuhoajafunktio T& operator[](long indeksi); // Indeksointioperaattori const T& operator[](long indeksi) const; // Indeksointioperaattori (const) Taulukko<T>& operator=(const Taulukko<T>& rhs); // Sijoitusoperaattori ; Mallit Mallin runko näyttää lähes samanlaiselta kuin tavallisen luokankin määrittely. Erona on se, että T esiintyy monessa paikassa. Esimerkiksi jäsenmuuttuja alkiot on tyyppiä osoitin tyyppiin T (sama kuin T-tyyppinen taulukko ). Kun mallista muodostetaan luokan määrittely, T korvataan todellisella tyypillä. Jos muodostamme mallista double-tyyppisen ilmentymän, alkiot on tyyppiä double-tyyppinen taulukko. Käytämme tyyppiä size_t jäsenelle koko, joka tallettaa taulukon alkioiden lukumäärän. Tämä on standardi kokonaislukutyyppi, joka on määritelty standardiotsikkotiedostossa cstddef ja vastaa sizeof()-operaattorin palauttaman paluuarvon tyyppiä. Se on suositeltava tyyppi taulukon koon määrittelyssä. Huomaa, miten ensimmäinen muodostinfunktio on esitelty explicit-määreellä. Koska tälle funktiolle välitetään vain yksi parametri, voimme kirjoittaa muodostinfunktion kutsun kahdella tavalla: Taulukko<int>yksi(5); Taulukko<int>kaksi = 5; // eksplisiittinen muoto //sijoitustyyppinen muoto Kun esittelemme muodostinfunktion explicit-määreellä, kiellämme jälkimmäisen muodon käytön. Kiellämme myöskin kokonaislukujen välittämisen funktiolle, joka vaatii taulukon. Indeksointioperaattori on uudelleenmääritelty const-tyyppiseksi. Ei-const-tyyppistä versiota käytetään ei-const-tyyppisten taulukoiden kohdalla ja se palauttaa ei-const-tyyppisen viittauksen taulukon alkioon. Eli tämä versio voi olla sijoitusoperaattorin vasemmalla puolella. consttyyppistä versiota käytetään const-tyyppisten olioiden kohdalla ja se palauttaa const-tyyppisen viittauksen taulukon alkioon. Tämä ei luonnollisestikaan voi olla sijoitusoperaattorin vasemmalla puolella. 711

6 C++ Ohjelmoijan käsikirja Kopioivan sijoitusoperaattorin kohdalla käytämme tyyppiä Taulukko<T>&. Kun luokka muodostetaan mallista - kun T on esimerkiksi tyyppi double - se on viittaus tämän kyseisen luokan nimeen, joka on Taulukko<double>. Yleisesti sanottuna mallin ilmentymän nimi muodostuu mallin nimestä, jonka perässä on kulmasulkeiden sisällä varsinainen tyyppi. Kulmasulkeiden sisällä olevien parametrien jälkeen tulevaa mallin nimeä kutsutaan mallin ID:ksi. Sinun ei tarvitse käyttää täydellistä mallin ID:tä mallin määrittelyssä. Mallin rungossa pelkkä Taulukko tarkoittaa samaa kuin Taulukko<T> ja Taulukko& tulkitaan samaksi kuin Taulukko<T>&, joten voimme yksinkertaistaa mallin määrittelyn: template <typename T> class Taulukko private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä public: explicit Taulukko(size_t taulkoko); Taulukko(const Taulukko& ataul); ~Taulukko(); T& operator[](long indeksi); const T& operator[](long indeksi) const; Taulukko& operator=(const Taulukko& rhs); ; // Muodostinfunktio // Kopiomuodostin // Tuhoajafunktio // Indeksointioperaattori // Indeksointioperaattori (const) // Sijoitusoperaattori Jos sinun täytyy viitata malliin mallin rungon ulkopuolelta, sinun tulee käyttää mallin ID:tä. Törmäämme tällaiseen tilanteeseen, kun määrittelemme mallin jäsenfunktioita myöhemmin tässä luvussa. 712 Sijoitusoperaattorin avulla voit sijoittaa taulukon toiseen taulukkoon - tätähän et voi tehdä C++:n tavallisten taulukoiden kohdalla. Jos jostain syystä haluat estää tämän toiminnallisuuden, sinun tulee kuitenkin esitellä operator=()-funktio mallin jäseneksi. Jos et esittele, julkinen oletussijoitusoperaattori luodaan mallin ilmentymälle tarvittaessa. Sijoitusoperaattorin käytön estät esittelemällä sen luokan yksityiseksi jäseneksi - tällöin siihen ei päästä käsiksi. Tallöin funktiolle ei tietenkään tarvita minkäänlaista toteutusta, koska C++ ei vaadi toteuttamaan jäsenfunktiota, ellei sitä käytetä - ja tätähän ei käytetä. Mallin jäsenmuuttujien määrittely Voit sijoittaa mallin jäsenfunktioiden määrittelyt mallin runkoon. Tällöin ne ovat avoimia (inline) kaikissa mallin ilmentymissä, aivan samaan tapaan kuin tavallistenkin luokkien kohdalla. Haluat varmastikin joskus määritellä jäsenfunktiot mallin rungon ulkopuolella, varsinkin, jos ne sisältävät runsaasti koodia. Kun näin teet, syntaksi on hieman erilainen ja näyttää aluksi varsin pelottavalta, joten katsotaan sitä nyt. Johtolankana on, että mallin jäsenfunktioiden määrittelyt ovat mallifunktioita. Mallifunktion, joka määrittelee jäsenfunktion, parametriluettelon tulee olla sama kuin malliluokan. Jos tämä kuulostaa sekavalta, yksityiskohtien käsittely helpottaa ymmärtämistä. Voimme nyt kirjoittaa Taulukko-mallimme jäsenfunktiot. Aloitamme muodostinfunktiosta.

7 Kun määrittelet sen mallin määrittelyn ulkopuolella, muodostinfunktion nimen yhteydessä tulee kirjoittaa mallin nimi, samaan tapaan kuin tavallisen luokan jäsenfunktion kohdalla. Tämä ei kuitenkaan ole funktion määrittely, vaan mallifunktion määrittely, joten se täytyy kertoa selvästi. Seuraavassa on muodostinfunktion määrittely: template <typename T> // Malli, jonka parametrinä on T Taulukko<T>::Taulukko(size_t taulkoko) : koko(taulkoko) // Taulukko<T> määrittelee mallin alkiot = new T[koko]; Mallit Ensimmäinen rivi kertoo, että kyseessä on malli, ja määrittelee myöskin malliparametriksi T:n. Mallifunktion esittelyn jakaminen kahdelle riville on ainoastaan lukemisen helpottamiseksi, eikä jakamista tarvitse tehdä, jos koko rakennelma mahtuu yhdelle riville. Muodostinfunktion nimen, Taulukko<T>, määrittelyssä malliparametri on välttämätön, koska se sitoo funktion määrittelyn malliluokkaan. Huomaa, että tässä ei käytetä typedef-avainsanaa - sitä käytetään ainoastaan malliparametrien listassa. Parametrilista ei ole välttämätön muodostinfunktion nimen perässä. Kun muodostinfunktio muodostetaan mallifunktion ilmentymäksi, tyypin nimi, esimerkiksi double, korvaa T:n. Eli muodostinfunktion nimi luokalle Taulukko<double> on tällöin Taulukko<double>::Taulukko(). Muodostinfunktiossa meidän tulee varata muistia vapaasta muistista alkiot-taulukolle, jossa on koko alkioita, jotka ovat tyyppiä T. Jos T on luokkatyyppi, luokassa T tulee olla julkinen oletusmuodostinfunktio. Jos näin ei ole, tämän muodostinfunktion ilmentymä ei käänny. Operaattori new muodostaa bad_alloc-poikkeuksen, jos muistia ei jostain syystä voida varata, joten Taulukko-luokan muodostinfunktiota tulee yleensä käyttää try-lohkossa. Tuhoajafunktion tulee vapauttaa alkiot-taulukon muisti, joten sen määrittely on seuraava: template <typename T> Taulukko<T>::~Taulukko() delete[] alkiot; Vapautamme tässä taulukolle varatun muistin, joten meidän tulee käyttää delete-operaattorin taulukkomuotoa. Kopiomuodostimen tulee luoda saman kokoinen uusi taulukko kuin parametrinä oleva taulukko, ja kopioida parametritaulukon sisältö uuteen taulukkoon. Kopiomuodostimen koodi näyttää seuraavalta: template <typename T> Taulukko<T>::Taulukko(const Taulukko& ataul) koko = ataul.koko; alkiot = new T[koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = ataul.alkiot[i]; 713

8 C++ Ohjelmoijan käsikirja Tässä oletetaan, että sijoitusoperaattori toimii luokalle T. Kuten muistat, sijoitusoperaattorin määrittely on erittäin tärkeää luokille, jotka varaavat muistia dynaamisesti. Jos luokassa T ei sitä määritellä, T:n oletuskopiomuodostinta käytetään, jolloin tulee epätoivottuja sivuvaikutuksia sellaisten luokkien yhteydessä, joita käsittelimme luvussa 13. Jos et katso mallin koodia ennen sen käyttöä, et ehkä huomaa riippuvuutta sijoitusoperaattorista. Funktio operator[]() on varsin suoraviivainen, mutta meidän tulee varmistaa, että vain sallittuja indeksin arvoja voidaan käyttää. Jos indeksin arvo ei ole sallittu, muodostamme poikkeuksen: template <typename T> T& Taulukko<T>::operator[](long indeksi) if(indeksi < 0 indeksi >= koko) throw out_of_range(indeksi < 0? "Negatiivinen indeksi" : "Indeksi liian suuri"); return alkiot[indeksi]; Voisimme määritellä myös oman poikkeusluokkamme, mutta on helpompi lainata out_of_rangeluokkaa, joka on jo valmiiksi määritelty standardikirjaston stdaxcept-otsikkotiedostossa. Poikkeus muodostetaan, jos esimerkiksi string-tyyppisen olion kohdalla indeksin arvo on sallittujen rajojen ulkopuolella. Muodostamme out_of_range-tyyppisen poikkeuksen, jos indeksi:n arvo ei ole välillä 0 ja koko-1. Muodostinfunktion parametri on string-olio, joka kuvaa virheen. Poikkeusolion jäsenfunktio what() palauttaa null-merkkiin päättyvän merkkijonon (tyyppi const char*). out_of_range-luokan muodostinfunktiolle välitämme yksinkertaisen viestin, mutta voit halutessasi lisätä viestiin tietoa indeksin arvosta ja taulukon koosta, jolloin ongelma on helpompi löytää koodista. Indeksointi-operaattorin const-versio on lähes samanlainen: template <typename T> const T& Taulukko<T>::operator[](long indeksi) const if(indeksi < 0 indeksi >= koko) throw out_of_range(indeksi < 0? "Negatiivinen indeksi" : "Indeksi liian suuri"); return alkiot[indeksi]; Viimeinen tarvitsemamme mallifunktio on sijoitusoperaattori. Sen tulee vapauttaa kohteena olevan olion varaama muisti ja sen jälkeen tehdä se, mitä kopiomuodostinkin teki - tietysti sen jälkeen, kun se on testannut, että oliot eivät ole samat: template <typename T> Taulukko<T>& Taulukko<T>::operator=(const Taulukko& rhs) if(&rhs == this) // Jos lhs == rhs return *this; // palautetaan lhs if(alkiot) delete[]alkiot; // Jos lhs-taulukko on olemassa // vapautetaan varattu muisti 714 koko = rhs.koko; alkiot = new T[rhs.koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = rhs.alkiot[i];

9 Vasemmanpuoleisen operandin vertaaminen oikeanpuoleiseen on tässä välttämätöntä, muutoin vapauttaisimme alkiot-jäsenen varaaman muistin, jonka jälkeen yrittäisimme kopioida sen, vaikka sitä ei enää ole olemassa. Eri operandien kohdalla vapautamme vasemman operandin varaaman muistin ennen kuin kopioimme oikeanpuoleisen operandin. Kaikki tässä kirjoittamamme määrittelyt ovat mallifunktioita varten ja ne ovat kiinteästi sidotut malliluokkaan. Ne eivät ole funktioiden määrittelyjä, ne ovat malleja, joita kääntäjä käyttää, kun niiden mukainen koodi tulee muodostaa. Eli niiden tulee olla saatavilla kaikissa mallia käyttävissä lähdetekstitiedostoissa. Tästä syystä sijoitamme mallin kaikkien jäsenfunktioiden määrittelyt otsikkotiedostoon, joka sisältää itse mallinkin. Vaikka voit määritellä mallin jäsenfunktiot erillisinä mallifunktioina, ne voivat silti olla avoimia. Pyydät kääntäjää käsittelemään ne avoimina, kun lisäät inline-avainsanan template<>:n perässä olevan määrittelyn alkuun: template <typename T> inline const T& Taulukko<T>::operator[](long indeksi) const if(indeksi < 0 indeksi >= koko) throw out_of_range(indeksi < 0? "Negatiivinen indeksi" : "Indeksi liian suuri"); return alkiot[indeksi]; Mallin ilmentymien luominen Kääntäjä luo mallin ilmentymän, kun ohjelmassa esitellään olio, jonka tyyppi on malli: Taulukko<int> tieto(40); Mallit Tämän kääntämiseksi tarvitaan kaksi asiaa - tyypin Taulukko<int> tulee olla esitelty, jotta tyyppi tunnistetaan ja muodostinfunktion tulee olla olemassa, koska sitä kutsutaan luomaan olio. Tämä lause luo mallimme ilmentymän, joka on luokka Taulukko<int>, sekä tämän luokan muodostinfunktion ilmentymän. Tässä oli kaikki, mikä on tarpeellista tieto-olion luomiselle, joten tässä oli kaikki, mitä kääntäjä tekee tässä vaiheessa. Ohjelmaasi lisättävän luokan määrittely muodostetaan sijoittamalla int T:n paikalle mallin määrittelyssä, mutta tässä on eräs vaikeus. Kääntäjä kääntää vain ne jäsenfunktiot, joita ohjelmasi käyttää, ei välttämättä koko luokkaa, joka voitaisiin luoda yksinkertaisella malliparametrin korvauksella. data-olion esittelyn kannalta se vastaa seuraavaa: class Taulukko<int> private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä 715

10 C++ Ohjelmoijan käsikirja ; public: Taulukko(size_t taulkoko); // Muodostinfunktio Kuten huomaat, muodostinfunktiota lukuun ottamatta luokan jäsenfunktiota ei tässä ole lainkaan. Kääntäjä ei luo minkään sellaisen ilmentymiä, joita ei tarvita olion luomiseen, eikä kääntäjä ota mukaan mitään mallin osia, joita ei tarvita ohjelmassasi. Tästä seuraa se, että mallin koodissa saattaa olla jopa virheitä ja ohjelmasi kääntyy, linkittyy ja sitä voidaan suorittaa normaalisti. Jos virheet ovat mallin osissa, joita ei ohjelmassa tarvita, niitä ei ehkä huomata, koska ne sisältävää koodia, jota ei oteta mukaan käännettävään koodiin. Ohjelmassasi on lähes varmasti muitakin lauseita kuin olion luominen, johon tarvitaan muodostinfunktiota - tuhoajafunktiota tarvitaan ainakin olion tuhoamiseen - joten luokan lopulliseen versioon kuuluu varmasti enemmän kuin mitä edellä näytettiin. Mallin ilmentymän muodostamista esittelystä kutsutaan mallin implisiittiseksi ilmentämiseksi, koska se tapahtuu olion pala-palalta muodostamisena. Tämä erottaa sen myös mallin eksplisiittisestä ilmentämisestä, jota käsittelemme hetken kuluttua ja joka toimii hieman eri tavalla. Kuten mainitsimme, data:n esittely saa aikaan myös muodostinfunktion, Taulukko<int>::Taulukko(), kutsun, joten kääntäjä luo mallifunktion avulla luokan muodostinfunktion määrittelyn: Taulukko<int>::Taulukko(long taulkoko) : koko(taulkoko) alkiot = new int[koko]; Joka kerta, kun käytät malliluokkaa eri tyyppisen muuttujan luomiseen, uusi luokka määritellään ja lisätään ohjelmaasi. Koska luokan olion luominen vaatii muodostinfunktion kutsumisen, saman tyyppinen muodostinfunktio muodostetaan myöskin samalla. Luonnollisestikaan sellaisen olion luominen, jonka tyyppinen mallin ilmentymä on jo muodostettu, ei saa aikaan uuden ilmentymän luomista. Kääntäjä osaa tarvittaessa käyttää aiemmin muodostettua ilmentymää. Kun kutsut mallin tietyn ilmentymän jäsenfunktiota - esimerkiksi silloin, kun kutsut mallista luodun olion jäsenfunktiota - jokaisen käytettävän jäsenfunktion koodi muodostetaan. Jos mallilla on jäsenfunktioita, joita et ohjelmassasi käytä, niiden mallien ilmentymiä ei luoda lainkaan. Jokaisen funktion määrittelyn muodostaminen on mallin implisiittinen ilmentäminen, koska se tapahtuu itse funktion käytön ulkopuolella. Malli itse ei ole osa suoritettavaa koodia, sen tarkoituksena on vain mahdollistaa se, että kääntäjä voi automaattisesti muodostaa tarvittavan koodin. 716

11 Mallit template<typename T> class Taulukko // Mallin määrittely... ; taulukko<int> data(40); Kääntäjä muodostaa malliparametrien mukaisen luokan määrittelyn - mallin ilmentymän. Taulukko<string> viestit(20); Mallin parametrit liitetään luokan määrittelyyn. Jokaisen esittelyn kohdalla, jossa on yydet malliparametrit, uusi luokan määrittely luodaan. class Yaulukko<int> // Luokan määrittely... //...tarpeen mukaan ; Mallin kukin ilmentymä muodostetaan vain kerran. Jos tarvittava ilmentymä on jo olemassa, sitä käytetään. Taulukko<int> arvot(60); class Taulukko<string> // Luokan määrittely... //...tarpeen mukaan ; Huomaa, että malli muodostetaan implisiittisesti, kun oliotyyppi tulee muodostaa. Oliotyyppiin osoittavan osoittimen esittely ei saa aikaan mallin ilmentämistä. Esimerkiksi: Taulukko<string>*pOlio; Tämä esittelee osoitin tyyppiin Taulukko<string> -tyyppisen polio-olion. Taulukko<string>tyyppistä oliota ei tämän lauseen vaikutuksesta luoda, joten myöskään mallin ilmentymää ei luoda. Tämän vastakohtana on lause: Taulukko<string*> pviesti(10); Tämä saa aikaan mallin ilmentymän luomisen. Se esittelee Taulukko<string*>-tyyppisen olion luomisen, joten pviesti:n jokainen alkio voi tallettaa osoittimen string-olioon. Luokan muodostinfunktion määrittely mallista muodostetaan samalla. Kokeillaan nyt Taulukko-malliamme esimerkin avulla. Kokeile itse - Mallin käyttö Voimme sijoittaa mallin määrittelyn ja mallin jäsenfunktioiden määrittelyt otsikkotiedostoon Taulukko.h: // Taulukko-mallin määrittely #ifndef TAULUKKO_H #define TAULUKKO_H #include <iostream> #include <stdexcept> using namespace std; // Poikkeus-luokat 717

12 C++ Ohjelmoijan käsikirja template <typename T> class Taulukko private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä public: explicit Taulukko(size_t taulkoko); // Muodostinfunktio Taulukko(const Taulukko& ataul); // Kopiomuodostin ~Taulukko(); // Tuhoajafunktio T& operator[](long indeksi); // Indeksointioperaattori const T& operator[](long indeksi) const; // Indeksointioperaattori (const) Taulukko& operator=(const Taulukko& rhs); // Sijoitusoperaattori ; // Muodostinfunktio template <typename T> // Malli, jonka parametrinä on T Taulukko<T>::Taulukko(size_t taulkoko) : koko(taulkoko) // Taulukko<T> määrittelee mallin alkiot = new T[koko]; // Kopiomuodostin template <typename T> Taulukko<T>::Taulukko(const Taulukko& ataul) koko = ataul.koko; alkiot = new T[koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = ataul.alkiot[i]; // Tuhoajafunktio template <typename T> Taulukko<T>::~Taulukko() delete[] alkiot; // Indeksointioperaattori template <typename T> T& Taulukko<T>::operator[](long indeksi) if(indeksi < 0 indeksi >= koko) throw out_of_range(indeksi < 0? "Negatiivinen indeksi" : "Indeksi liian suuri"); return alkiot[indeksi]; // Indeksointioperaattori (const) template <typename T> const T& Taulukko<T>::operator[](long indeksi) const if(indeksi < 0 indeksi >= koko) throw out_of_range(indeksi < 0? "Negatiivinen indeksi" : "Indeksi liian suuri"); 718 return alkiot[indeksi];

13 Mallit // Sijoitusoperaattori template <typename T> Taulukko<T>& Taulukko<T>::operator=(const Taulukko& rhs) if(&rhs == this) // Jos lhs == rhs return *this; // palautetaan lhs if(alkiot) delete[]alkiot; // Jos lhs-taulukko on olemassa // vapautetaan varattu muisti koko = rhs.koko; alkiot = new T[rhs.koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = rhs.alkiot[i]; #endif Tarvitsemme mallin käyttämiseen ohjelman, joka esittelee joitakin taulukoita mallin avulla. Kokeilemme myös joitakin kiellettyjä indeksien arvoja: // Esimerkki 18.1 Mallin käyttö #include "Laatikko.h" #include "Taulukko.h" #include <iostream> #include <iomanip> using namespace std; int main() const int doublelkm = 50; Taulukko<double> arvot(doublelkm); try for(int i = 0 ; i < doublelkm ; i++) arvot[i] = i + 1; // Luodaan mallin ilmentymä // Luodaan jäsenfunktion ilmentymä cout << endl << "Alkioparien summat:"; int rivit = 0; for(int i = doublelkm - 1 ; i >= 0 ; i--) cout << (rivit++ % 5 == 0? "\n" : "") << setw(5) << arvot[i] + arvot[i - 1]; catch(const out_of_range& ex) cout << endl <<"out_of_range-poikkeus muodostettu! " << ex.what(); try const int ltklkm = 10; Taulukko<Laatikko> laatikot(ltklkm); // Luodaan mallin ilmentymä for(int i = 0 ; i <= ltklkm ; i++) cout << endl << "Laatikon tilavuus on " << laatikot[i].tilavuus(); // Luodaan jäsenen ilmentymä 719

14 C++ Ohjelmoijan käsikirja catch(const out_of_range& ex) cout << endl << "out_of_range-poikkeus muodostettu! " << ex.what(); cout << endl; return 0; Otsikkotiedosto Laatikko.h sisältää luvun 16 Laatikko-luokan määrittelyn ja tarvitset ohjelmassa myös Laatikko-luokan jäsenfunktioiden määrittelyt sisältävää Laatikko.cpp-tiedostoa. Esimerkin tulostus näyttää seuraavalta: Alkioparien summat: out_of_range-poikkeus muodostettu! Negatiivinen indeksi Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 Laatikon tilavuus on 1 out_of_range-poikkeus muodostettu! Indeksi liian suuri Kuinka se toimii main()-funktion alussa luomme Taulukko<double>-tyyppisen olion käyttämällä mallia malliparametrillä double: Taulukko<double> arvot(doublelkm); // Luodaan mallin ilmentymä Tämä lause esittelee arvot Taulukko<double>-tyyppiseksi ja alkioiden lukumäärä ilmoitetaan muuttujalla doublelkm. Kun kääntäjä käsittelee tämän lauseen, se luo mallista luokan Taulukko<double> määrittelyn. Jotta olio arvot voidaan luoda, tarvitaan muodostinfunktion kutsu (Taulukko<double>::Taulukko(doubleLkm)), joten kääntäjä muodostaa muodostinfunktion muodostinfunktion mallista. 720

15 Alustamme arvot-taulukon alkiot 1 - doublelkm try-lohkossa olevassa for-silmukassa: Mallit for(int i = 0 ; i < doublelkm ; i++) arvot[i] = i + 1; // Luodaan jäsenfunktion ilmentymä Lauseke arvot[i] saa aikaan indeksointioperaattorin ilmentymän luomisen. Sitä kutsutaan implisiittisesti muodossa arvot.operator[](i). Koska arvot ei ole const-tyyppinen, ei-constversiota käytetään. Käytämme try-lohkossa toista for-silmukkaa, joka tulostaa peräkkäisten alkioiden summan, alkaen taulukon lopusta: for(int i = doublelkm - 1 ; i >= 0 ; i--) cout << (rivit++ % 5 == 0? "\n" : "") << setw(5) << arvot[i] + arvot[i - 1]; Tämä kutsuu myöskin indeksointioperaattoria, mutta mallifunktion ilmentymä on jo muodostettu, joten uutta ilmentymää ei muodosteta. Lausekkeella arvot[i - 1] on selvästikin kielletty indeksin arvo, kun i on 0, joten tällöin muodostetaan operator[]()-funktiossa poikkeus. Seuraava käsittelijä käsittelee poikkeuksen: catch(const out_of_range& ex) cout << endl <<"out_of_range-poikkeus muodostettu! " << ex.what(); out_of_range-poikkeuksen what()-funktio palauttaa null-merkkiin päättyvän merkkijonon, joka vastaa muodostinfunktiolle poikkeusolion luonnissa välitettyä string-oliota. Tulostuksesta huomaat, että uudelleenmääritelty operaattorifunktio muodosti Negatiivinen indeksi -poikkeuksen. Kun indeksointioperaattori muodostaa poikkeuksen, ohjelman suoritus siirtyy välittömästi poikkeuksen käsittelijään, joten kiellettyä alkion viittausta ei käytetä, eikä mitään talleteta kielletyn indeksin viittamaan paikkaan. Silmukan suoritus myöskin päättyy tässä kohtaa. Seuraavassa try-lohkossa määrittelemme olion, joka voi tallettaa Laatikko-olioiden taulukon: Taulukko<Laatikko> laatikot(ltklkm); // Luodaan mallin ilmentymä Nyt kääntäjä muodostaa mallin ilmentymän Taulukko<Laatikko>, joka tallettaa Laatikko-olioiden taulukon. Ilmentymä muodostetaan, koska mallin ilmentymää ei ole vielä muodostettu Laatikkoolioille. Tämä lause kutsuu myöskin tämän luokan muodostinfunktiota, joten muodostinfunktion mallin ilmentymä luodaan. Taulukko<Laatikko>-luokan muodostinfunktio kutsuu Laatikkoluokan oletusmuodostinfunktiota, kun luokan alkiot-jäsen luodaan vapaasta muistista. Kaikkien alkiot-talukon Laatikko-olioiden kokona on oletusarvoisesti 1 * 1 * 1. Tulostamme kunkin Laatikko-olion tilavuuden for-silmukassa: for(int i = 0 ; i <= ltklkm ; i++) cout << endl << "Laatikon tilavuus on " << laatikot[i].tilavuus(); // Luodaan jäsenen ilmentymä 721

16 C++ Ohjelmoijan käsikirja Lauseke laatikot[i] kutsuu uudelleenmääriteltyä indeksointioperaattoria, joten kääntäjä käyttää jälleen mallifunktiota funktion määrittelyn muodostamiseen. Kun i:n arvo on ltklkm, indeksointioperaattori muodostaa poikkeuksen, koska ltklkm viittaa laatikot-taulukon loppukohdan yli. try-lohkon perässä oleva catch-lohko käsittelee poikkeuksen: catch(const out_of_range& ex) cout << endl << "out_of_range-poikkeus muodostettu! " << ex.what(); Koska poistumme try-lohkosta, kaikki paikallisesti esitellyt oliot tuhotaan, mukaan lukien laatikot-olio. arvot-olio on tässä kohdassa vielä olemassa, koska sitä ei luotu edellisessä trylohkossa ja se on yhä näkyvyysalueella. Mallien vienti Mallin jäsenfunktioiden koodin sijoittamisella otsikkotiedostoon on se huono puoli, että kääntäjän täytyy käsitellä sama koodi jokaisen lähdetekstitiedoston kohdalla, johon otsikkotiedosto on sisällytetty. Tämä voi aiheuttaa huomattavan lisätyön laajoissa ohjelmissa, joissa käytetään runsaasti malleja. Vaihtoehtoisena ratkaisuna on sijoittaa jäsenfunktioiden mallit erilliseen lähdetekstitiedostoon ja antaa se kaikkien mallia tarvitsevien lähdetekstitiedostojen saataville. Kaikki, mitä sinun tarvitsee tehdä, on viedä mallifunktioiden määrittelyt export-avainsanalla: // TaulukkoMalli.cpp-tiedosto #include <iostream> #include <stdexcept> #include "Array.h" using namespace std; // Poikkeus-luokat // Muodostinfunktio export template <typename T> // Malli, jonka malliparametri on T Taulukko<T>::Taulukko(size_t taulkoko) : koko(taulkoko) // Taulukko<T> määrittelee mallin alkiot = new T[koko]; // Kopiomuodostin export template <typename T> Taulukko<T>::Taulukko(const Taulukko& ataul) koko = ataul.koko; alkiot = new T[koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = ataul.alkiot[i]; // Ja kaikki muut jäsenfunktioiden mallit kuten ennenkin, mutta export-avainsanalla Tämä tiedosto voidaan nyt kääntää erikseen, ja muodostettua objektitiedostoa voidaan käyttää kaikissa mallia käyttävissä ohjelmissa. 722

17 Otsikkotiedosto Taulukko.h sisältää mallin kuten ennenkin, mutta ainoastaan mallifunktioiden esittelyt tarvitaan: // Taulukko-mallin määrittely #ifndef TAULUKKO_H #define TAULUKKO_H // Mallin määrittely kuten ennenkin template <typename T> class Taulukko private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä Mallit public: explicit Taulukko(size_t taulkoko); Taulukko(const Taulukko& ataul); ~Taulukko(); T& operator[](long indeksi); const T& operator[](long indeksi) const; Taulukko& operator=(const Taulukko& rhs); ; // Muodostinfunktio // Kopiomuodostin // Tuhoajafunktio // Indeksointioperaattori // Indeksointioperaattori (const) // Sijoitusoperaattori #endif Nyt kaikkien ohjelmien, jotka haluavat käyttää mallia, tulee sisällyttää lyhyempi versio Taulukko.h-otsikkotiedostosta sitä tarvitsevaan lähdetekstitiedostoon. Lisäksi tarvitaan TaulukkoMalli.cpp-tiedosto tai siitä muodostettu objektitiedosto linkityksen yhteydessä. Ainoastaan sellaiset mallifunktiot voidaan viedä, jotka eivät ole avoimia. Jos käytät exportavainsanaa avoimen mallifunktion yhteydessä, sitä ei huomioida. Jos viet mallin määrittelyn, määrittelyä ei saa toistaa missään muualla ohjelmassa. Ainoastaan vietyjen mallien esittely voi olla muissa lähdetekstitiedostoissa. Et voi viedä mallia, joka on määritelty nimettömässä nimiavaruudessa. Mallin staattiset jäsenet Mallilla voi olla staattisia jäseniä, aivan samaan tapaan kuin tavallisellakin luokalla voi olla. Mallin staattiset jäsenfunktiot ovat varsin suoraviivaisia. Jokainen mallin ilmentymä ilmentää staattisen jäsenfunktion tarvittaessa. Tällaisella jäsenfunktiolla ei ole this-osoitinta eikä näin ollen voi viitata luokan ei-staattisiin jäseniin. Staattisten jäsenfunktioiden määrittelemisellä mallille on samat säännöt kuin luokankin kohdalla ja mallin staattiset jäsenfunktiot käyttäytyvät mallin kunkin ilmentymän kohdalla samaan tapaan kuin tavallisen luokankin kohdalla. Staattinen jäsenmuuttuja on hieman kiinnostavampi, koska se tulee alustaa mallin määrittelyn ulkopuolella. Oletetaan, että Taulukko-mallimme sisältää staattisen jäsenmuuttujan. Jäsenen esittely ja sen alustava malli näyttävät seuraavalta: template <typename T> class Taulukko private: static T arvo; // Staattinen jäsenmuuttuja T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä 723

18 C++ Ohjelmoijan käsikirja public: explicit Taulukko(size_t taulkoko); Taulukko(const Taulukko& ataul); ~Taulukko(); T& operator[](long indeksi); const T& operator[](long indeksi) const; Taulukko& operator=(const Taulukko& rhs); ; template < typename T > T Taulukko<T>::arvo; // Muodostinfunktio // Kopiomuodostin // Tuhoajafunktio // Indeksointioperaattori // Indeksointioperaattori (const) // Sijoitusoperaattori // Alustetaan staattinen // jäsenmuuttuja Alustus suoritetaan mallin avulla. Staattinen jäsenmuuttuja on aina riippuvainen sen mallin malliparametreistä, jonka jäsenenä se on, joten meidän tulee alustaa arvo mallilla, jonka malliparametrinä on T. Staattisen muuttujan nimen yhteyteen tulee kirjoittaa myös tyypin nimi Taulukko<T>, jotta se tunnistetaan mallin ilmentymään. Et voi tässä käyttää pelkkää Taulukkotyyppiä, koska sen määrittely on mallin rungon ulkopuolella ja mallin ID on Taulukko<T>. 724 Mallin ei-tyyppiparametrit Ei-tyyppiparametri näyttää samalta kuin funktion parametri - tyypin nimen perässä on parametrin nimi. Parametrissä välitetään täten tietyntyyppinen arvo. Et voi kuitenkaan käyttää mitä tahansa tyyppiä mallin ei-tyyppiparametrinä. Ei-tyyppiparametrit on tarkoitettu käytettäviksi määrittelemään arvoja, jotka saattavat olla hyödyllisiä säiliön määrittelyssä, kuten taulukon koko tai indeksin ylä- ja alarajat. Ei-tyyppiparametri voi olla vain kokonaislukutyyppinen, kuten int tai long, lueteltu tyyppi, osoitin tai viittaus olioon, kuten string* tai Laatikko&, osoitin tai viittaus funktioon tai osoitin luokan jäseneen. Tästä voit päätellä, että ei-tyyppiparametri ei voi olla liukulukutyyppinen tai luokan olio, eli tyypit double, Laatikko ja string eivät ole sallittuja, ei myöskään string**. Pidä mielessä, että ei-tyyppiparametrin päätarkoitus on säiliön koon ja arvoalueen rajojen määrittely. Ei-tyyppiparametrissä välitettävä arvo voi tietystikin olla myös luokan olio, jos parametrin tyyppi on viittaus. Jos parametrin tyyppi on esimerkiksi Laatikko&, voit käyttää Laatikko-tyyppistä oliota parametrin arvona. Ei-typpiparametri kirjoitetaan kuten funktion parametrikin, tyypin nimen perään kirjoitetaan parametrin nimi: template <typename T, size_t koko> class LuokanNimi // Määrittelyt T:n ja koon avulla... Tällä mallilla on tyyppiparametri T ja ei-tyyppiparametri koko. Määrittely esitetään näiden kahden parametrin ja mallin nimen avulla. Jos haluat, tyyppiparametrin nimi voi olla myös eityyppiparametrin tyyppi: template <typename T, size_t koko, T arvo> class LuokanNimi // T on tyyppiparametrin nimi // T on myös ei-tyyppiparametrin tyyppi

19 Mallit // Määrittely T:n koon ja arvon avulla... ; Tällä mallilla on T-tyyppinen ei-tyyppiparametri arvo. Parametrin T tulee esiintyä parametrilistassa ennen sen käyttöä, eli arvo ei tässä voi olla parametrin T edellä. Huomaa, että kun samaa symbolia käytetään sekä tyyppiparametrinä että ei-tyyppiparametrin tyyppinä, rajoitetaan samalla typename-parametrin arvot ei-tyyppiparametrille sallittujen tyyppien mukaan (toisin sanoen T:n tulee olla kokonaislukutyyppinen). Havainnollistaaksemme, miten voit käyttää ei-tyyppiparametrejä, oletetaan, että määrittelet taulukon mallin seuraavasti: template <typename T, in taulkoko, T arvo> class Taulukko // Määrittely T:n koon ja arvon avulla... Nyt voit käyttää muodostinfunktiossa ei-tyyppiparametriä arvo alustamaan taulukon jokaisen alkion: template <typename T, int taulkoko, T arvo> Taulukko<T, koko, arvo>::taulukko(size_t taulkoko) : koko(taulkoko) alkiot = new T[taulKoko]; for(int i = 0 ; i < taulkoko, i++) alkiot[i] = arvo; Koska ei-tyyppiparametrin tyyppi voi olla vain kokonaislukutyyppi, osoitin tai viittaus, et voi luoda Taulukko-oliota, joka tallettaa double-arvoja, joten tämän mallin käyttökelpoisuus on hieman heikko. Ei-tyyppiparametrien esimerkki Parempana esimerkkinä voimme käyttää aikaisempaa Taulukko-malliamme lisäämällä siihen eityyppiparametrin, jonka avulla taulukon indeksointiin saadaan hieman joustavuuta: template <typename T, long alkuindeksi> class Taulukko private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä public: explicit Taulukko(size_t taulkoko); Taulukko(const Taulukko& ataul); ~Taulukko(); T& operator[](long indeksi); const T& operator[](long indeksi) const; Taulukko& operator=(const Taulukko& rhs); ; // Muodostinfunktio // Kopiomuodostin // Tuhoajafunktio // Indeksointioperaattori // Indeksointioperaattori (const) // Sijoitusoperaattori 725

20 C++ Ohjelmoijan käsikirja Tässä malliin on lisätty long-tyyppinen ei-tyyppiparametri alkuindeksi. Tämän ideana on, että voit määritellä mitä arvoja indeksi voi saada, esimerkiksi , jolloin esittelisit taulukon ei-tyyppiparametrin arvoksi -10 ja muodostinfunktion parametrin arvoksi 21, koska taulukossa tarvitaan tällöin 21 alkiota. Koska mallilla on nyt kaksi parametriä, jäsenfunktiot määrittelevillä mallifunktioilla tulee olla myöskin sama määrä parametrejä. Näin myös silloin, kun jokin funktio ei tarvitse eityyppiparametriä lainkaan. Parametrit ovat osa mallin tunnistetta, joten jotta funktio täsmää malliin, sillä tulee olla sama parametrilista. Edellä esitetyllä on joitakin vakavia haittapuolia. Uuden malliparametrin alkuindeksi lisäämisellä on se seuraus, että parametrien erilaiset arvot muodostavat eri mallin ilmentymät. Tämä tarkoittaa sitä, että double-tyyppinen taulukko, jonka indeksit alkavat arvosta 0, on eri tyyppi kuin double-tyyppinen taulukko, jonka indeksit alkavat arvosta 1. Jos käytät ohjelmassasi molempia, kaksi erillistä luokan määrittelyä muodostetaan mallista, mukaan lukien kaikki jäsenfunktiot. Tällä on vähintään kaksi epätoivottua seurausta - ensinnäkin, ohjelmasi sisältää huomattavasti enemmän käännettyä koodia kuin odotit. Toiseksi (mikä on vielä huonompi asia), et voi sekoittaa näiden kahden tyypin alkioita samaan lausekkeeseen. Indeksien arvovälin määrittely on huomattavasti parempi sijoittaa muodostinfunktion parametriksi kuin mallin eityyppiparametriksi: template <typename T> class Taulukko private: T* alkiot; // T-tyyppinen taulukko size_t koko; // Taulukon alkioiden lukumäärä long alku // Indeksin alkuarvo public: explicit Taulukko(size_t taulkoko, long alkuindeksi = 0); // Muodostinfunktio Taulukko(const Taulukko& ataul); // Kopiomuodostin ~Taulukko(); // Tuhoajafunktio T& operator[](long indeksi); // Indeksointioperaattori const T& operator[](long indeksi) const; // Indeksointioperaattori (const) Taulukko& operator=(const Taulukko& rhs); // Sijoitusoperaattori ; Uusi jäsen, alku, tallettaa indeksin alkuarvon, joka määritellään muodostinfunktion toisena parametrinä. Parametrin alkuindeksi oletusarvo on nolla, joten normaalia indeksointia käytetään oletusarvoisesti. Nyt onkin mielenkiintoista nähdä, miten jäsenfunktiot määritellään, kun meillä on eimalliparametri. Muodostetaan muutama mallifunktio, joita tarvitsemme Taulukko-mallille. Jäsenfunktioiden mallit Koska olemme lisänneet mallin määrittelyyn ei-tyyppiparametrin, muodostinfunktion malli ja muiden jäsenfunktioiden mallit tulee muuttaa myöskin. Muodostinfunktion malli muuttuu muotoon: 726

21 Mallit template <typename T, long alkuindeksi> Taulukko<T, alkuindeksi>::taulukko(size_t taulkoko) : koko(taulkoko) alkiot = new T[koko]; Mallin ID on nyt Taulukko<T, alkuindeksi>, joten sitä käytetään muodostinfunktion nimen määrittelyssä. Tämä on ainut muutos uuden malliparametrin lisäämisen lisäksi. Kopiomuodostimen kohdalla meidän tulee tehdä samantyyppisiä muutoksia: template <typename T, long alkuindeksi> Taulukko<T, alkuindeksi>::taulukko(const Taulukko& ataul) koko = ataul.koko; alkiot = new T[koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = ataul.alkiot[i]; Ulkoinen indeksointi ei tietystikään vaikuta mitenkään asioiden sisäiseen käsittelyyn. Tuhoajafunktioon tulee myöskin lisätä uusi malliparametri: template <typename T, long alkuindeksi> Taulukko<T, alkuindeksi>::~taulukko() delete[] alkiot; Ei-const-tyyppisen indeksointioperaattorin mallifunktion määrittely tulee muuttaa muotoon: template <typename T, long alkuindeksi> T& Taulukko<T, alkuindeksi>::operator[](long indeksi) if(indeksi < alkuindeksi indeksi > alkuindeksi + static_cast<long>(koko) - 1) throw out_of_range(indeksi < alkuindeksi? "Negatiivinen indeksi" : "Indeksi liian suuri"); return alkiot[indeksi - alkuindeksi]; Tässä on jo varsin merkitseviä muutoksia. Indeksin indeksi arvo tarkistetaan nyt siten, että se on ei-tyyppiparametrin ja taulukon alkioiden lukumäärän mukaan sallittu. Indeksin arvot voivat olla arvovälillä alkuindeksi - alkuindeksi+koko-1. Koska size_t on usein etumerkitön kokonaislukutyyppi, meidän tulee eksplisiittisesti muuntaa se long-tyyppiseksi, muutoin kaikki muut arvot muutetaan size_t-tyyppisiksi, joka saa aikaan väärän tuloksen, jos arvot ovat negatiivisia. Poikkeuksen valitseva lauseke on myös muuttunut. const-tyyppinen versio tulee muuttaa samaan tapaan: template <typename T, long alkuindeksi> const T& Taulukko<T, alkuindeksi>::operator[](long indeksi) const 727

22 C++ Ohjelmoijan käsikirja if(indeksi < alkuindeksi indeksi > alkuindeksi + static_cast<long>(koko) -1) throw out_of_range(indeksi < alkuindeksi? "Negatiivinen indeksi" : "Indeksi liian suuri"); return alkiot[indeksi - alkuindeksi]; Lopuksi meidän tulee muuttaa sijoitusoperaattorin mallia, mutta ainoastaan mallin parametrilista ja mallin ID tarvitsee muuttaa: template <typename T, long alkuindeksi> Taulukko<T, alkuindeksi>& Taulukko<T, alkuindeksi>::operator=(const Taulukko& rhs) if(&rhs == this) // Jos lhs == rhs return *this; // palautetaan lhs if(alkiot) olemassa delete[]alkiot; // Jos lhs-taulukko on // vapautetaan varattu muisti koko = rhs.koko; alkiot = new T[rhs.koko]; for(int i = 0 ; i < koko ; i++) alkiot[i] = rhs.alkiot[i]; Mallin ei-tyyppiparametrin käytölle on rajoituksia. Käytännössä sinun ei tule muuttaa parametrin arvoa mallin määrittelyssä. Toisin sanoen, ei-tyyppiparametriä ei voi käyttää sijoitusoperaattorin vasemmalla puolella, eikä siihen voi soveltaa lisäys- eikä vähennysoperaattoria - eli sitä pidetään vakiona. Luvussa 9 näimme, kuinka mallifunktion malliparametrit voitiin päätellä funktion parametreistä. Näin ei ole malliluokan kohdalla. Mallin kaikki parametrit tulee aina määritellä, ellei parametreillä ole oletusarvoja - tätä käsittelemme myöhemmin tässä luvussa. Ei-tyyppiparametrien arvot Ei-tyyppiparametrin, joka ei ole viittaus tai osoitin, arvon tulee olla käännösaikainen vakiolauseke. Tämä tarkoittaa sitä, että et voi käyttää parametrin arvona lauseketta, jossa on muita kuin const-tyyppisiä kokonaislukumuuttujia. Tämä on pienoinen haitta, mutta kääntäjä pystyy tällöin tarkistamaan arvon, mikä on taas hyvä asia. Esimerkiksi seuraavat lauseet eivät käänny: long alku = -10; Taulukko<double, alku> arvot(21); // Ei käänny! 728 Kääntäjä muodostaa virheilmoituksen, että toinen arvo ei ole sallittu. Näiden kahden lauseen oikea versio on: const long alku = -10; Taulukko<double, alku> arvot(21); Kun alku on nyt esitelty const-tyyppiseksi, kääntäjä voi luottaa sen arvoon ja molemmat malliparametrien arvot ovat sallitut.

23 Kääntäjä voi myös suorittaa parametrien arvojen standardimuunnokset, jos sellaisia tarvitaan oikean parametrityypin löytämiseksi. Jos meillä olisi esimerkiksi const size_t-tyyppiseksi esitelty ei-tyyppiparametri, kääntäjä muuntaa kokonaislukuliteraalin, kuten 10, parametrin tyyppiseksi. Osoittimet ja taulukot ei-tyyppiparametreinä Ei-tyyppiparametrin, joka on osoitin, arvon tulee olla osoite, mutta se ei voi olla vanha osoite. Sen tulee olla sellaisen olion osoite, jolla on ulkoinen linkitys, joten et voi esimerkiksi käyttää taulukon alkioiden osoitteita tai luokan ei-staattisten jäsenten osoitteita. Tämä tarkoittaa myös sitä, että jos ei-tyyppiparametrisi on const char* -tyyppinen, et voi käyttää merkkijonoliteraalia parametrin arvona. Jos haluat käyttää merkkijonoliteraalia parametrin arvona, sinun tulee alustaa osoitinmuuttuja merkkijonoliteraalin osoitteella ja välittää tämä osoitin parametrinä. Koska osoitin on sallittu mallin ei-tyyppiparametri, voit määritellä taulukon parametriksi, mutta taulukko ja osoitin eivät aina ole vaihtoehtoisia välitettäessä mallille parametri. Jos esimerkiksi määrittelet mallin seuraavasti: template <long* pnumero> class OmaLuokka // Mallin määrittely... Mallit Voit nyt muodostaa tämän mallin ilmentymiä seuraavalla koodilla: long data[10]; long* pdata = data; // Globaali // Globaali OmaLuokka<pData> arvot; OmaLuokka<data> arvot; Joko taulukon nimeä tai osoitinta sopivaan tyyppiin voidaan käyttää osoitintyyppisen parametrin arvona. Tämä ei kuitenkaan onnistu toisin päin. Oletetaan, että olisimme määritelleet mallin seuraavasti: template <long numero[10]> class ToinenLuokka // Mallin määrittely... Parametri on tässä 10-alkioinen taulukko, ja parametrin arvon tulee olla samaa tyyppiä. Tässä tapauksessa voimme kirjoittaa esittelyn käyttämällä edellä esiteltyä data-taulukkoa: ToinenLuokka<data> numerot; // OK Et voi kuitenkaan käyttää osoitinta, joten seuraava lause ei käänny: ToinenLuokka<pData> numerot; // Ei sallittu! Huolimatta Taulukko-mallimme heikkouksista, tarkastellaan ei-tyyppiparametrejä esimerkin avulla. 729

24 C++ Ohjelmoijan käsikirja Kokeile itse - Ei-tyyppiparametrien käyttö Tee edellä käsittelemämme muutokset Taulukko-mallin sisältävään otsikkotiedostoon. Voimme nyt kokeilla uusia ominaisuuksia seuraavan esimerkin avulla: // Esimerkki 18.2 Mallin ei-tyyppiparametrien käyttö #include "Laatikko.h" #include "Taulukko.h" #include <iostream> #include <iomanip> using namespace std; int main() try const int koko = 21; const int alku = -10; const int loppu = alku + koko - 1; Taulukko<double, alku> arvot(koko); for(int i = alku; i <= loppu ; i++) arvot[i] = i - alku + 1; // Taulukon alkioiden lukumäärä // Ensimmäisen alkion indeksi // Viimeisen alkion indeksi // Esitellään taulukko double-arvoille // Alustetaan alkiot cout << endl<< "Alkioparien summat: "; int rivit = 0; for( int i = loppu ; i >= alku ; i--) cout << (rivit++ % 5 == 0? "\n" : "") << setw(5) << arvot[i] + arvot[i - 1]; catch(const out_of_range& ex) cout << endl << "out_of_range-poikkeus muodostettu! " << ex.what(); catch(const exception& ex) cout << endl << ex.what(); try const int alku = 0; const int koko = 11; Taulukko<Laatikko, alku - 5> laatikot(koko); for(int i = alku - 5 ; i <= alku + koko - 5 ; i++) cout << endl << "Laatikon tilavuus on " << laatikot[i].tilavuus(); catch(const exception& ex) cout << endl << typeid(ex).name() << "-poikkeus muodostettu! "<< ex.what(); 730 cout << endl; return 0;

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

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

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

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

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

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

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

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

Virtuaalifunktiot ja polymorfismi

Virtuaalifunktiot ja polymorfismi 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.

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

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

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

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

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

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

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

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

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

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

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

Funktiomallit. 10.1 Funktiomallin määrittely

Funktiomallit. 10.1 Funktiomallin määrittely 10 Funktiomallit Tässä luvussa kuvataan, mikä funktiomalli on, ja tuodaan esille, kuinka niitä määritellään ja käytetään. Funktiomallin käyttö on melko yksinkertaista ja monet aloittelevat C++-ohjelmoijat

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

Sisältö. 22. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä Sisältö 22. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko metodin parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 22.1 22.2 Yleistä

Lisätiedot

Listarakenne (ArrayList-luokka)

Listarakenne (ArrayList-luokka) Listarakenne (ArrayList-luokka) Mikä on lista? Listan määrittely ArrayList-luokan metodeita Listan läpikäynti Listan läpikäynti indeksin avulla Listan läpikäynti iteraattorin avulla Listaan lisääminen

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

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 2. Taulukot. Yleistä. Yleistä Sisältö 2. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.1 2.2 Yleistä

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

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 7. huhtikuuta 2017 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille. Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma. 2. Taulukot 2.1 Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.2 Yleistä

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

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

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

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

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

7. Näytölle tulostaminen 7.1

7. Näytölle tulostaminen 7.1 7. Näytölle tulostaminen 7.1 Sisällys System.out.println- ja System.out.print-operaatiot. Tulostus erikoismerkeillä. Edistyneempää tulosteiden muotoilua. 7.2 Tulostusoperaatiot System.out.println-operaatio

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

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

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

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

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 16.2.2010 1 / 41 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

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

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

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

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

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

Muuttujien roolit Kiintoarvo cin >> r;

Muuttujien roolit Kiintoarvo cin >> r; Muuttujien roolit Muuttujilla on ohjelmissa eräitä tyypillisiä käyttötapoja, joita kutsutaan muuttujien rooleiksi. Esimerkiksi muuttuja, jonka arvoa ei muuteta enää kertaakaan muuttujan alustamisen jälkeen,

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

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, literaalivakio, nimetty vakio Tiedon merkkipohjainen tulostaminen 1 Tunnus Java tunnus Java-kirjain Java-numero

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

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

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

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

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

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

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 22. huhtikuuta 2016 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille! Kirjoittamasi luokat, funktiot ja aliohjelmat

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

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

14. Poikkeukset 14.1

14. Poikkeukset 14.1 14. Poikkeukset 14.1 Sisällys Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla poikkeuksella? Poikkeusten heittäminen.

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

INSIDE C++ Ohjelmoijan käsikirja. Ivor Horton WROX PRESS

INSIDE C++ Ohjelmoijan käsikirja. Ivor Horton WROX PRESS INSIDE C++ Ohjelmoijan käsikirja Ivor Horton WROX PRESS C++ Ohjelmoijan käsikirja Kirjoittanut Kääntäjä Kansi Kustantaja Ivor Horton Jouni Laaksonen Frank Chaumont IT Press PL 25 00511 HELSINKI Sähköpostiosoite

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

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. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä

Sisällys. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä Sisällys 11. Javan toistorakenteet Laskuri- ja lippumuuttujat.. Tyypillisiä ohjelmointivirheitä: Silmukan rajat asetettu kierroksen verran väärin. Ikuinen silmukka. Silmukoinnin lopettaminen break-lauseella.

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

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit.

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit. 3. Muuttujat ja operaatiot Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi.. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit. Arvojen

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet String-merkkijonoluokka 1 Ohjelmointikielten merkkijonot Merkkijonot ja niiden käsittely on välttämätöntä ohjelmoinnissa Valitettavasti ohjelmointikielten tekijät eivät tätä ole ottaneet

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

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

Operaattorin ylikuormitus ja käyttäjän muunnokset

Operaattorin ylikuormitus ja käyttäjän muunnokset 13 Operaattorin ylikuormitus ja käyttäjän muunnokset Luvussa 7, "Ominaisuudet, taulukot ja indeksoijat," opit, miten luokan yhteydessä käytetään ohjelmallisesti []-operaattoria, jolloin objektia voidaan

Lisätiedot

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokista Javan alkeistietotyypit ja vastaavat kääreluokat Autoboxing Integer-luokka Double-luokka Kääreluokista Alkeistietotyyppiset muuttujat (esimerkiksi

Lisätiedot

3. Muuttujat ja operaatiot 3.1

3. Muuttujat ja operaatiot 3.1 3. Muuttujat ja operaatiot 3.1 Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi. Operaattorit. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit.

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

14. oppitunti. Operaattorin ylikuormitus. Osa. Operaattorin ylikuormittaminen

14. oppitunti. Operaattorin ylikuormitus. Osa. Operaattorin ylikuormittaminen Osa IV 14. oppitunti Operaattorin ylikuormitus Edellisessä luvussa opit ylikuormittamaan metodeita ja luomaan kopiomuodostimen, joka tekee syvän kopion. Tässä luvussa käsitellään seuraavia aiheita: Kuinka

Lisätiedot

5.6. C-kielen perusteet, osa 6/8, Taulukko 6.1.2008, pva, kuvat jma

5.6. C-kielen perusteet, osa 6/8, Taulukko 6.1.2008, pva, kuvat jma 5.6. C-kielen perusteet, osa 6/8, Taulukko 6.1.2008, pva, kuvat jma Every cloud has a silver line. - englantilainen sananlasku Tässä osiossa tärkeää: yksi- ja moniulotteinen taulukko Sisältö Yleistä Yksiulotteinen

Lisätiedot

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu Taulukot Taulukon määrittely ja käyttö Taulukko metodin parametrina Taulukon sisällön kopiointi toiseen taulukkoon Taulukon lajittelu esimerkki 2-ulottoisesta taulukosta 1 Mikä on taulukko? Taulukko on

Lisätiedot

Tietotyypit ja operaattorit

Tietotyypit ja operaattorit Tietotyypit ja operaattorit Luennossa tarkastellaan yksinkertaisten tietotyyppien int, double ja char muunnoksia tyypistä toiseen sekä esitellään uusia operaatioita. Numeeriset tietotyypit ja muunnos Merkkitieto

Lisätiedot

Osa VII. Mitä mallit ovat ja kuinka niitä käytetään Miksi mallit tarjoavat paremman vaihtoehdon makroille Kuinka luokkamalleja luodaan

Osa VII. Mitä mallit ovat ja kuinka niitä käytetään Miksi mallit tarjoavat paremman vaihtoehdon makroille Kuinka luokkamalleja luodaan Osa VII 23. oppitunti Mallit Muutaman viime vuoden aikana on C++ -kieleen lisätty joitakin uusia piirteitä. Eräs kiinnostavimpia ja tehokkaimpia uusia C++ -ominaisuuksia ovat mallit. Mallit mahdollistavat

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 7.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 7.2.2011 1 / 39 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Rakenteiset tietotyypit Moniulotteiset taulukot

Rakenteiset tietotyypit Moniulotteiset taulukot C! Rakenteiset tietotyypit Moniulotteiset taulukot 22.2.2018 Agenda Rakenteiset tietotyypit Vilkaisu 6. kierroksen tehtäviin Moniulotteiset taulukot Esimerkki Seuraava luento to 8.3. Ilmoittautuminen ohjelmointikokeeseen

Lisätiedot

Johdatus Ohjelmointiin

Johdatus Ohjelmointiin Johdatus Ohjelmointiin Syksy 2006 Viikko 2 13.9. - 14.9. Tällä viikolla käsiteltävät asiat Peruskäsitteitä Kiintoarvot Tiedon tulostus Yksinkertaiset laskutoimitukset Muuttujat Tiedon syöttäminen Hyvin

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

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Sisällys. 14. Poikkeukset. Johdanto. Johdanto Sisällys 14. Poikkeukset Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla poikkeuksella? Poikkeusten heittäminen.

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

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, Vakio Tiedon merkkipohjainen tulostaminen Ohjelmointi (ict1tx006) Tunnus (5.3) Javan tunnus Java-kirjain Java-numero

Lisätiedot

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Sisällys. 14. Poikkeukset. Johdanto. Johdanto Sisällys 14. Poikkeukset Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Miten varautua poikkeukseen metodissa? Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla

Lisätiedot

VIII. Osa. Liitteet. Liitteet Suoritusjärjestys Varatut sanat Binääri- ja heksamuoto

VIII. Osa. Liitteet. Liitteet Suoritusjärjestys Varatut sanat Binääri- ja heksamuoto Osa VIII Liitteet Liitteet A B C Suoritusjärjestys Varatut sanat Binääri- ja heksamuoto Osa VIII A. Liite Operaattoreiden suoritusjärjestys On tärkeää ymmärtää, että operaattoreilla on prioriteettinsa,

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

Standardi mallikirjasto

Standardi mallikirjasto Standardi mallikirjasto 20 Standardi mallikirjasto Kuten jo tiedätkin C++ sisältää laajan standardikirjaston, joka yksinkertaistaa monia ohjelmointitehtäviä. Tähän saakka näkemäsi lisäksi tämä kirjasto

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

Demo 6 vastauksia. 1. tehtävä. #ifndef #define D6T1 H D6T1 H. #include <iostream> using std::ostream; using std::cout; using std::endl;

Demo 6 vastauksia. 1. tehtävä. #ifndef #define D6T1 H D6T1 H. #include <iostream> using std::ostream; using std::cout; using std::endl; Demo 6 vastauksia 1. tehtävä #ifndef #define D6T1 H D6T1 H #include using std::ostream; using std::cout; using std::endl; #include using std::string; 10 template class

Lisätiedot

Osio2: Taulukot Jukka Juslin

Osio2: Taulukot Jukka Juslin Osio2: Taulukot Jukka Juslin Jukka Juslin 1 Taulukot Taulukot ovat olioita, jotka auttavat meitä organisoimaan suuria määriä tietoa Seuraavassa keskitymme näihin: Taulukon tekeminen ja käyttö Rajojen tarkastus

Lisätiedot

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys 812347A Olio-ohjelmointi, 2015 syksy 2. vsk V Geneerisyys Sisältö 1. Johdanto geneerisyyteen 2. Geneeriset funktiot 3. Geneeriset luokat 4. Standard Template Library (STL) 5. IOStream-kirjasto 812347A

Lisätiedot

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4 Sisällys 12. Näppäimistöltä lukeminen Arvojen lukeminen näppäimistöltä yleisesti. Arvojen lukeminen näppäimistöltä Java-kielessä.. Luetun arvon tarkistaminen. Tietovirrat ja ohjausmerkit. Scanner-luokka.

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

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