|  |
| --- |
| **Programmeerimise paradigmad** |
| * Imperatiivne
	+ Struktureeritud
		- Protseduraalne
		- Objektorienteeritud
			* Klassipõhine
			* Prototüübipõhine
* Deklaratiivne
	+ Funktsionaalne
	+ Loogiline
* Metaprogrammeerimine
	+ Üldistav
		- Mall
	+ Reflektiivne
 |
| * v
* r
 |

**Mall** (inglise keeles *template*) on programmeerimisel 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.

Ü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.remove(20); // kustuta loendist elemendid väärtusega 20
minuList.sort(); // sorteeri loend

```

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);
}

```

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 või kasutuses 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.

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.

Vaata ka
--------

* C++
* Polümorfism
* Programmeerimine
* Programmeerimiskeel