Yleiskäyttöisyysongelma ratkaistaan esittelemällä cList-luokka luokkamallin(muotti) avulla:
/* LISTTEMP.CPP
...
Tehtäviä 1) Peri luokasta luokka cList2, joka on kaksisuuntainen ja
jossa voidaan siis liikkua kumpaankin suuntaan.
2) Toteuta cList "oikeana" dynaamisena listana.
3) Peri tehtävän 2 listasta 2-suuntainen lista.
Onnistuuko kunnolla?
4) Jäsenfunktiot first,last ja next ovat oikeastaan
tarpeettomia, koska sama ominaisuus saadaan aikaan
tobegin, toend, forward ja current -funktioiden avulla.
Kuitenkin joskus tarvitaan ainakin kahta toisistaan
riippumattomasti listaa käsittelevää "iteraattoria".
Esitä ratkaisuehdotus, jolla lista voidaan samanaikaisesti
tulostaa sekä alusta että lopusta päin, eli esim lista 1 2 3
tulostuisi: 1 3 2 2 3 1
*/
...
template <class TYPE>
class cList {
protected:
int nelem; // Alkioiden lukumäärä
TYPE data[MAX_ELEM]; // Alkioden taulukko.
int cursor; // Sijainti listassa
public:
cList() { nelem = 0; tobegin(); }
~cList() { nelem = 0; }
int out() const { return ( cursor < 0 || nelem <= cursor ); }
int tobegin() { cursor = 0; return out(); }
int forward() { ++cursor; return out(); }
int toend() { cursor = nelem-1; return out(); }
TYPE current() const { return data[inside(0,cursor,nelem-1)]; }
...
}; /* cList */
...
int main(void)
{
...
cList<char> lc; lc.add('a'); lc.add('b'); lc.add('c'); lc.add('d');
for (char c=lc.first(); !lc.out(); c=lc.next() ) cout << c << " ";
...
cList<double> ld; ld.add(1.2); ld.add(20.3); ld.add(300.4); ld.add(400.5);
for (double d=ld.first(); !ld.out(); d=ld.next() ) cout << d << " ";
...
cList<cPiste> lp; lp.add(cPiste(1,1)); lp.add(cPiste(2,4));
for (cPiste p=lp.first(); !lp.out(); p=lp.next() ) cout << p << " ";
...
cList<int> li; li.add(1); li.add(2); li.add(3);
for (li.tobegin(); !li.out(); li.forward() ) cout << li.current() << " ";
...
}
Template toimii siis lähes kuten #define. Luokasta monistuu eri
versio kutakin tyyppiä kohti (generoitu luokka
= template class).
Jos monistuminen haluttaisiin välttää, pitäisi luokasta
tehdä void -osoittimia käsittelevä versio.
Tällöinkin kannattaa template:lla tehdä apuluokat
tyypinmuunnoksia varten.Template on voimassa vain luokan määrittelyn lopettavaan puolipisteeseen. Mikäli esimerkiksi funktio add haluttaisiin tehdä ei-inline-funktiona, pitäisi template aloittaa uudelleen jokaista funktiota kohden:
...
template <class TYPE>
int cList<TYPE>::empty() const {
return ( nelem == 0 );
}
template <class TYPE>
int cList<TYPE>::add(TYPE p)
{
if ( nelem >= MAX_ELEM ) return 1;
data[nelem++] = p;
return 0;
}