Mall (programmeerimine)
Vajab toimetamist |
Programmeerimisel on mallid (i.k. template) C++ keele omadus, mis võimaldab kirjutada koodi hoolimata sellest, mis andmetüüpidega seda koodi kasutama hakatakse.
Mallid abistavad üldistavat programmeerimist C++ keeles.
Mallid on suurepärane abivahend C++ programmeerijatele, eriti kui neid kombineerida mitmese pärimise (multiple inheritance) ja operaatorite ülelaadimisega (operator overloading). C++ Standard Template Library on üles ehitatud mallidel ning pakub programmeerijale töö lihtsustamiseks palju erinevaid klassimalle ja funktsioone.
Sisukord |
[redigeeri] Ülevaade
Malle on põhiliselt kahte tüüpi. Funktsioonimall käitub nagu funktsioon, mille argumentideks võivad olla erinevad andmetüübid. Näiteks, C++ Standard Template Library sisaldab funktsioonimalli max(x, y) mis tagastab x või y, sõltuvalt kumb on suurem. Selle funktsiooni mall võib olla defineeritud järgnevalt
template <typename T> T max(T x, T y) { if (x < y) return y; else return x; }
Sellist malli võib välja kutsuda täpselt nagu funktsioonigi:
cout << max(3, 7); // väljastab 7
Kompilaator uurib kompileerides selle malli argumente ja näeb, et T on int tüüpi, ning genereerib mallist järgnevaga samaväärse funktsiooni:
int max(int x, int y) { if (x < y) return y; else return x; }
Selline tehnika töötab, mis iganes tüüpi x ja y ka ei oleks, ainsateks tingimusteks on see, et "x < y" annab bool'iks teisenduva väärtuse ning x ja y on sama tüüpi. Eritüübiliste x ja y puhul peab programmeerija kompilaatorit abistama, öeldes, mis T tüüp on, aga siis peavad nii x kui y olema teisendatavad programmeerija poolt antud tüübiks T. Kui programmeerija on defineerinud oma andmetüübi, on tal võimalus kirjeldada oma operaator < ja seega kasutada samamoodi max funktsiooni.
Klassimallid on sarnased funktsiooni mallidega, laiendades üldistamist klassidele. Klassimalle kasutatakse tihti üldistavate konteinerite loomiseks või veel teadmata andmetüüpide käsitlemiseks. Näiteks, STL'is on olemas list konteiner. Soovimaks luua loendit numbritest e. int, on vaja koodi kirjutada vaid
std::list<int> minuList;
ja minuList on olemas ning kasutatavad kõik list klassimalli funktsioonid, näiteks
minuList.push_back(10); // lisa lõppu nr 10 minuList.erase(20); // kustuta loendist nr 20 minuList.count(15); // loetle 15-te hulk
[redigeeri] Plussid ja miinused
Mõningaid mallide sarnaseid omadusi on võimalik realiseerida ka eelprotsessori (i.k. preprocessor) makrosid kasutades. Näiteks, siin on max() makrona:
#define max(a,b) ((a) < (b) ? (b) : (a))
Nii makrod kui mallid viiakse oma lõplikku vormi kompileerimise ajal. Ei saa öelda, et üks oleks kiirem kui teine, kuid mallide kompileerimine võib kesta kauem kui makrode puhul. Lõpliku programmi kiirusel vahet ei ole. Eelpool defineeritud mall-funktsioonil max ja siin defineeritud makrol max on mõned olulised erinevused:
- ühte makro argumentidest arvutatakse 2 korda, mall-funktsiooni kumbagi argumenti täpselt 1 kord
- mall-funktsiooni argumendid peavad olema sama tüüpi, vastasel korral peab programmeerija ise kompilaatorile ütlema, milliste tüüpidega tegemist on e.
void f(int a, long b) { max<int>(a, b); }
- kui mõlemad makro argumendid on lvalue'd (e. sellise tüübiga, mida sobib paigutada omistamisoperaatorist vasakule poole), saab teha nii:
void f(int& a, long& b) { // omistatame argumendile, mille väärtus suurem on, 42. max(x, y) = 42; }
Malle loetakse suureks edasiarenduseks võrreldeks makrodega. Mallid on tüübikindlad, e. type-safe. Nende kasutamisel ilmneb enamus andmetüüpide erinevusest tingitud vigu juba kompileerimise faasis, mitte programmi töötamise ajal. Mallid on loodud haaramaks laiemalt programmeerimise probleeme kui makrod.
Samas, on mallide kasutamisel peamiselt kolm vastuargumenti. Esiteks, mitmed kompilaatorid on ajalooliselt viletsa mallide toega, seega kasutades palju malle, võib kood muutuda mõnevõrra vähem universaalseks (e. portable). Teiseks, pea kõik kompilaatorid näitavad mittemidagiütlevaid või raskesti mõistetavaid veateateid, kui mallide lähtekoodis on vigasid. Kolmandaks, mallide kasutamine võib kompilaatorit sundima genereerima mitu korda enam koodi (i.k. template instantiation) kui tavaliselt, seega võib programmi suurus märgatavalt kasvada.
[redigeeri] Mallid teistes keeltes
Mallid jäeti välja mitmetest C++il baseeruvatest keeltest, nagu Java ja C#, suuresti mallide võimaliku väärkasutuse ja sellest tulenevate probleemide tõttu. Neis keeltes on teised meetodid üldistava programmeerimise praktiseerimiseks. Kuid siiski, Java ja C# tulevastesse versioonidesse lisatakse väidetavalt mallidega võrreldavad võimalused, et parendada üldistava programmeerimise tuge.
[redigeeri] Vaata ka
- C++
- Üldistav programmeerimine
- Polümorfism
- Programmeerimine
- Programmeerimiskeel
- C++ Mall-metaprogrammeerimine