Tarkastellaan aluksi seuraavaa ongelmaa: halutaan tehdä luokka list, johon voidaan tallettaa yksittäisiä kirjaimia. Yksinkertaisuuden vuoksi luokka toteutetaan seuraavassa taulukon avulla, mutta luokan ulkoinen käyttö ei muutu yhtään luokan sisäisen toteutuksen muuttuessa. Jotta cList-luokan alkioiden tyyppi olisi helppo muuttaa, on tyyppi esitelty #define:n avulla
/* LISTARR.CPP
Esimerkki (yksisuuntaisen) listan toteuttamisesta taulukon avulla.
Kaksi esimerkkiä mahdollisuuksista käydä lista kokonaan läpi.
joko: for (c=l.first(); !l.out(); c=l.next() ) -> käytä c ??
tai: for (l.tobegin(); !l.out(); l.forward() ) -> käytä l.current()
Ei tapahdu "vahinkoa", vaikka listaa yritetään käyttää liian pitkälle.
vl 6.11.1993
Tehtäviä 1) Peri luokasta luokka cList2, joka on kaksisuuntainen ja
jossa voidaan siis liikkua kumpaankin suuntaan.
2) Toteuta list "oikeana" dynaamisena listana.
3) Peri tehtävän 2 listasta 2-suuntainen lista.
Onnistuuko kunnolla?
4) Mitä tässä pitää muuttaa, mikäli halutaan käyttää
muun tyyppisiä listan alkioita?
Kokeile reaalilukuja ja piste-luokan alkioita!
(Piste-luokka ks. MYSTREAM.CPP)
5) Entä jos halutaan käyttää samassa ohjelmassa kahta
tai useampaa eri listaan menevää tyyppiä?
*/
#include <iostream.h>
inline int inside(int a,int x,int b) // x välille [a,b], jos b<a niin a
{ return b < a ? a : x < a ? a : x < b ? x : b; }
#define MAX_ELEM 100
#define TYPE char
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)]; }
TYPE first() { tobegin(); return current(); }
TYPE next() { forward(); return current(); }
TYPE last() { toend(); return current(); }
int empty() const { return ( nelem == 0 ); }
int add(TYPE p) { if ( nelem >= MAX_ELEM ) return 1;
data[nelem++] = p; return 0;
}
}; /* cList */
#define VIIVA "------------------------------------------------------------\n"
/****************************************************************************/
int main(void)
{
cout << VIIVA;
cList 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 << " ";
cout << c << "\n" << VIIVA;
for (lc.tobegin(); !lc.out(); lc.forward() )
cout << lc.current() << " ";
cout << lc.current() << "\n" << VIIVA;
return 0;
}
Luokka toimii varsin hyvin, kunnes tulee tarve käyttää
yhtäaikaa listaa esimerkiksi sekä kirjaimille, että
reaaliluvuille. Huomattakoon, että luokassa on tarjottu valmiit funktiot
listan kaikkien alkioiden läpikäymiseksi.