Luokan lisääminen dynaamisesti

Vesa Lappalainen (vesal@mit.jyu.fi)

Seuraavissa esimerkeissä on tavoitteena, että olisi talletusluokka Elaintarha, joka lukee tiedostoa ja tiedoston rivien perusteella luo sopivia oliota. Erityisenä tavoitteena on luokkien määrän lisääminen vain perimällä kantaluokasta uusi luokka ja linkittämällä tämä mukaan projektiin. Malliohjelmat lukevat seuraavan muotoista tiedostoa:

kissa:Misse;15;Miauuu
kissa:Mirri;6
koira:Musti;3
mato:Mato Matala;5;;45 

Luokkia voidaan käyttää seuraavaan tyyliin:

  cElaintarha elaintarha(20);
  elaintarha.lue("elukat.txt");
  elaintarha.tulosta();
  elaintarha.aantele();
  elaintarha.talleta(cout);

Esimerkit: (esimerkeissä luokkataulukot on toteutettu "kiinteän" kokoisilla taulukoilla, mutta ne on helposti vaihdettavissa dynaamisemmiksi. Etsintä tapahtuu O(n) algortimilla, mutta tämäkin voidaan vaihtaa suhteellisen helposti vaikka mapiksi tai vastaavaksi.)

mato.cpp Kantaluokassa on attribuutti tunnus ja se sisältää alussa mainitussa tiedostossa olevan luokan tunnisteen. Luokan edustajien pitää osata luoda itsensä kaltainen toinen edustaja. Ei vaadi kieleltä juuri mitään muuta kuin perinnän. Uuden tyypin lisääminen hoidetaan C++:ssa luomalla staattinen muuttuja, joka tallettaa itsensä ElaintarhanElaimet-tauluun. ElaintarhanElaimet on esimerkkikoelma kaikista tunnetuista luokista. Jossakin muussa kielessa (esim. Delphissa) luokan lisäys voitaisiin tehdä luokan esittelytiedoston alustus-osassa (initialization). Jos tällaistakaan ei ole kielessä, pitää tunnetut luokat lisätä esim. pääohjelman alussa.
matotype.cpp Vaatii kieleltä typeid -tyyppisen ominaisuuden. Talletettavien luokkien ei tarvitse pitää tunnus -atribuuttia. Esimerkissä tunnuksena käytetään aina luokan nimeä, mutta jos haluttaisiin käyttää muuta nimeä, voitaisiin tämä tehdä mato.cpp-esimerkin mukaisesti. Edelleen talletettavien luokkien pitää osata luoda itsensä klooni.
matotemp.cpp Luo automaattisesti template-funktion avulla luomisfunktion kullekin jälkeläisluokalle. Itse luokalta ei nyt vaadita juuri mitään. Vaatii kieleltä geneeriset funktiot. (Käytännössä ei kääntynyt Borland C++ Builder 3.0:lla, eikä g++ 2.7.???)
matop.dpr
elain.pas
mato.pas
erotastr.pas
Delphi-versio. Tunnuksena käytetään luokan nimeä. Luokkien ei tarvitse osata luoda kloonia (Delphi-luokat osaavat tämän aina). Luokkien lisääminen ElaintarhanElaimet-joukkoon tehdään initialization-osassa, ks.mato.pas.