// mato.cpp // // Vesa Lapplainen 7.2.1999 // Mukaellan Tero Pulkkisen ideaa sfnet.atk.ohjelmointi.moderoitu 5.2.1999 // Muutokset: // 8.2.1999/vl: korjattu delete alkiot delete [] alkiot; // // Malliohjelma, jossa naytetaan, miten voidaan tehdä luokkia, jotka // lukevat itsensa tiedostosta ja luovat tiedostossa olevan tunnuksen // mukaan eri jälkelaisten esiintymia. // Esimerkkiohjelma lukee seuraavan muotoista tiedostoa: // cKissa:Misse;15;Miauuu // cKissa:Mirri;6 // cKoira:Musti;3 // cMato:Mato Matala;5;;45 // // Luokat: // caElain - abstarkti kantaluokka elaimille // cElainAlkio - luo ja tallettaa yhden elain-luokan edustajan // osaa luoda vastaavan edustajan. Tietaa edustajan // "tunnuksen". Luonti tehdaan luomisfunktion // avulla, joka on esitelty uuden luokan yhteydessa // cElaintarhanElaimet - luokka, joka tallettaa malliksi yhden kunkin luokan // esiintyman. // cElaintarha - tallettaa kantaluokan jalkelaisia // cKissa,cKoira - mallijälkeläisiä // cMato - mallijälkeläinen, jossa mm. uusia attribuutteja // // // Uuden jalkelaisen tekemiseksi pitaa tehda luokka, jossa on esim: //------------------------------------------------------------------------------ // class cKoira : public caElain { // virtual const char *aanahdys() const { return "Hau"; } // public: // cKoira(string &s) : caElain(s) {} // }; // ja lisata luokkaa vastaavaan .cpp-tiedostoon rivi: // static cElainAlkio koira(tmpLuoElain); // // Jos luokassa on uusia attribuutteja, jotka pitaa myos tallettaa, pitaa // uudelleenmaaritella (override) metodit: // virtual void setAsString(string &s); // virtual string getAsString() const; #include #include #include #include #include //------------------------------------------------------------------------------ // Apufunktioita merkkijonojen käsittelyyn //------------------------------------------------------------------------------ string erota(string &jono, char merkki=' ',bool etsi_takaperin=false) { size_t p; if ( !etsi_takaperin ) p = jono.find(merkki); else p = jono.rfind(merkki); string alku = jono.substr(0,p); if ( p == string::npos ) jono = ""; else jono.erase(0,p+1); return alku; } int erota_int(string &jono, char merkki=' ',bool etsi_takaperin=false) { string ijono(erota(jono,merkki,etsi_takaperin)); int i=0; sscanf(ijono.c_str(),"%d",&i); return i; } string AsString(int i) { char s[50]; sprintf(s,"%d",i); return string(s); } //------------------------------------------------------------------------------ // Kantaluokka //------------------------------------------------------------------------------ class caElain { string nimi; int ika; string aantely; virtual const char *aanahdys() const = 0; public: virtual caElain *luo_samanlainen(string &s) const = 0; virtual void setAsString(string &s) { nimi = erota(s,';'); ika = erota_int(s,';'); aantely = erota(s,';'); } virtual string getAsString() const { return nimi + ";" + AsString(ika) + ";" + aantely; } caElain() { string s(""); setAsString(s); } caElain(string &s) { setAsString(s); } string aantelyAsString() const { if ( aantely != "" ) return aantely; else return aanahdys(); } void aantele(ostream &os=cout) const { os << aantelyAsString(); } }; typedef caElain *(*fpLuoElain)(string &s); template caElain *tmpLuoElain(string &s) { return new TYPE(s); } //------------------------------------------------------------------------------ class cElainAlkio { fpLuoElain luoelain; caElain *elain; string tunnus; public: cElainAlkio(fpLuoElain f); ~cElainAlkio() { delete elain; } int compare(const string s) const { return getTunnus().compare(s); } int compare(const caElain *e) const { return typeid(*e) != typeid(*elain); } caElain *luo(string &s) const { return luoelain(s); } const string &getTunnus() const { return tunnus; } }; class cElaintarhanElaimet { int lkm; int max_lkm; cElainAlkio **alkiot; public: cElaintarhanElaimet(int ml) { max_lkm = ml; lkm = 0; alkiot = new cElainAlkio *[ml]; } ~cElaintarhanElaimet() { delete [] alkiot; } int lisaa(cElainAlkio *uusi) { if ( lkm >= max_lkm ) return 1; alkiot[lkm] = uusi; lkm++; return 0; } cElainAlkio *etsi(const string &viitenimi) const; const string &etsi(const caElain *e) const; }; string tyhja("Ei eläintä"); cElainAlkio *cElaintarhanElaimet::etsi(const string &viitenimi) const { for (int i=0; icompare(viitenimi) == 0 ) return alkiot[i]; return NULL; } const string &cElaintarhanElaimet::etsi(const caElain *e) const { for (int i=0; icompare(e) == 0 ) return alkiot[i]->getTunnus(); return tyhja; } //------------------------------------------------------------------------------ cElaintarhanElaimet gElaintarhanElaimet(20); cElainAlkio::cElainAlkio(fpLuoElain f) : luoelain(f) { string s; elain = luoelain(s); tunnus =typeid(*elain).name(); gElaintarhanElaimet.lisaa(this); } //------------------------------------------------------------------------------ class cElaintarha { int lkm; int max_lkm; caElain **alkiot; public: cElaintarha(int ml) { max_lkm = ml; lkm = 0; alkiot = new caElain *[ml]; } ~cElaintarha() { poista_kaikki(); delete [] alkiot; } int lisaa(caElain *uusi) { if ( lkm >= max_lkm ) return 1; alkiot[lkm] = uusi; lkm++; return 0; } void poista_kaikki(); void tulosta(ostream &os) const; void aantele(ostream &os) const; int lue(istream &f); int lue(const string &tiedoston_nimi) { ifstream f(tiedoston_nimi.c_str()); if ( !f ) return 1; return lue(f); } int talleta(ostream &os) const; int talleta(const string &tiedoston_nimi) { ofstream f(tiedoston_nimi.c_str()); if ( !f ) return 1; return talleta(f); } }; void cElaintarha::tulosta(ostream &os=cout) const { for (int i=0; igetAsString() << endl; } void cElaintarha::aantele(ostream &os=cout) const { for (int i=0; iaantelyAsString() << " "; os << endl; } int cElaintarha::lue(istream &f) { string s,luokka; while ( !f.eof() ) { if ( !getline(f,s) ) return 1; luokka = erota(s,':'); cElainAlkio *ea = gElaintarhanElaimet.etsi(luokka); if ( !ea ) continue; lisaa(ea->luo(s)); } return 0; } int cElaintarha::talleta(ostream &f) const { for (int i=0; igetAsString() << endl; return 0; } void cElaintarha::poista_kaikki() { for (int i=0; i)); //static cElainAlkio kissa(luoKissa); //------------------------------------------------------------------------------ class cKoira : public caElain { virtual const char *aanahdys() const { return "Hau"; } public: virtual caElain *luo_samanlainen(string &s) const { return new cKoira(s); } cKoira(string &s) : caElain(s) {} }; //static cElainAlkio koira(tmpLuoElain); //------------------------------------------------------------------------------ class cMato : public caElain { int pituus; virtual const char *aanahdys() const { return "Siuh"; } public: virtual caElain *luo_samanlainen(string &s) const { return new cMato(s); } virtual void setAsString(string &s) { caElain::setAsString(s); pituus = erota_int(s); } // cMato(string &s) { setAsString(s); } // tai cMato(string &s) : caElain(s) { pituus = erota_int(s); } virtual string getAsString() const { return caElain::getAsString() + ";" + AsString(pituus); } }; //static cElainAlkio mato(tmpLuoElain); //------------------------------------------------------------------------------ int main(void) { /* string s1("Misse;15;Miauuu"); cKissa misse(s1); string s2("Mirri;6"); cKissa mirri(s2); string s3("Musti;3"); cKoira musti(s3); string s4("Mato Matala;5;;45"); cMato matala(s4); cout << misse.getAsString() << " " << misse.aantelyAsString() << endl; cout << mirri.getAsString() << " " << mirri.aantelyAsString() << endl; cout << matala.getAsString() << " " << matala.aantelyAsString() << endl; */ cElaintarha elaintarha(20); elaintarha.lue("elukat2.txt"); elaintarha.tulosta(); elaintarha.aantele(); elaintarha.talleta(cout); return 0; }