Gyakorló feladatok (12. hét)

Fontosabb kulcsszavak, fogalmak

  • OO modellezés
  • Heterogén kollekció
  • STL tárolók

Feladatok megoldásokkal

  1. Semmittevő hivatalnokok modellje: Egy irodában aktákat dolgoznak fel a hivatalnokok, melyeket véletlenszerűen az asztalukra dobálnak. Minden hivatalnoknak lehet beosztottja. Különböző munkakedvű hivatalnok létezik. Mi most a semmittevőt modellezzük, aki az asztalán levő akták és a beosztottai számától függően dolgozik:
    • Ha kap egy új aktát és pont annyi aktája van, mint ahány beosztottja, akkor az aktákat a beosztottai asztalára dobja.
    • Ha több aktája van, mint beosztottja, akkor az új aktát kidobja az ablakon.
  2. Modellezzük a hivatalnokokat és az irodát!
    • Azonosítsuk a szereplőket: (Hivatalnok, SemmittevoHivatalnok, Asztal, Akta, Iroda). Az egyszerűség kedvéért az aktát a Hivatalnok attribútumának képzeljük (int). Az Asztalt meg az irodában levő tároló elemek testesítik meg, akiknek van szomszédjuk.
    • Mivel több fajta hivatalnokunk lehet, célszerű közös ősből származtatni azokat. Ennek oka részben a közös viselkedés (mindenkinek lehet beosztottja), másrészt az irodában való közös elhelyezés igénye -> heterogén. Az alaposztály (Hivatalnok) tárolja a beosztottakat és az akták számát. Ezek az adatok elérhetők a leszármazottak számára (protected). A beosztottak tárolójáról feltételezzük, hogy indexelhető, de mást műveletét nem használjuk ki. (Nyelvi eszközökkel azonban ezt nem védjük.)
    • Rajzoljuk fel az osztályok közötti kapcsolatokat:
    • Deklaráljuk Hivatalnok és a SemmittevoHivalatnok osztályokat!
    • Valósítsuk meg a tagfüggvényeket! Mivel a semmittevoHivatalnok::meloJott() tagfüggvénye rekurzívan hívódhat (ld. köv feladat), ezt valahogy meg kell fogni. A rekurziót úgy fogjuk meg, hogy az akták számát nem nullázzuk le előre, amikor a beosztottak meloJott függvényét meghívjuk. Így egy esetleges rekurzív visszahívásnál az aktaszám biztosan nagyobb lesz mint a beosztottak száma. Ekkor meg nem csinálunk semmit. (Elvileg kellene vizsgálni, hogy van-e egyáltalán beosztottja, mert ha nincs, akkor az aktaszám nem nullázódik soha.)
    • Készítsen olyan irodát, ahol a hivatalnokok mátrix elrendezésben ülnek, és a beosztott fogalmat kicsit átértékeljük: mindenkinek a szomszédja a beosztottja. (Így a szomszédok egymás beosztottai lesznek, ezért ügyelni kell az estleges végtelen rekurzió elkerülésére!)
    • A Hivatalnokok létrehozását, és a beosztottak (szomszédok) az Iroda konstruktora végzi.
  3. Vizsgáljuk felül a Hivatalnok osztályt! A beosztottak tárolójáról feltételezzük, hogy tömbként indexelhető. Mást nem használunk ki, a SemmitevoHivatalnok-ban, de emiatt nem lehet pl. lista. Hogyan lehetne elrejteni a beosztottak tárolójának működését?

    A megoldás iterátor:
    class Hivatalnok {
    protected:
       typedef std::vector<Hivatalnok*>::iterator beoIter_t;
    ...
    };
    void SemmittevoHivatalnok::meloJott() {
       if (++aktak == beokSzama()) {   
    	for (beoIter_t i = beosztott.begin(); i != beosztott.end(); ++i)
                (*i)->meloJott();
            aktak = 0;  
       }
    }
    
  4. Hasonló gondolatmenettel az iroda konstruktorában is használhatnánk iterátort. Így bármilyen tárolónk lehetne.
    class Iroda {
        typedef vector<vector<Hivatalnok*> >::iterator sorIter_t; // a sort kijelölő iterátor (a sort tároló elemre mutat)
        typedef vector<Hivatalnok*>::iterator oszlIter_t;         // egy soron belül lépkedő iterátor (elemre mutat)
        vector<vector<Hivatalnok*> > iroda;
    public:
    ...
    };
    Iroda::Iroda(size_t sor, size_t oszlop) : iroda(sor, vector<Hivatalnok*>(oszlop)) {
        // Hivatalnokok létrehozása
        for (sorIter_t i = iroda.begin(); i != iroda.end(); i++)
    	for (oszlIter_t j = i->begin(); j != i->end(); j++)
    	    (*j) = new SemmittevoHivatalnok;
        // A közvetlen szomszédok a beosztottak
    ...
    }
    
  5. Legyen lekérdezhető az akták száma, és írja az asztaloknál levő akták számát ciklikusan egy-egy képfájlba úgy, hogy minden asztal egy képpontnak feleljen meg.
    Portable graymap (PGM) írása:
    A PGM egy egyszerű, szürkeárnyalatos képformátum, amit többek között az xnview programmal meg lehet nézni. Ehhez a file elejére kell egy header, ami szöveges infó. Ezt követik bináris formában az intenzitásértékek:
    P5
    <SOROK>
    <OSZLOPOK>
    255
    ITT JÖNNEK SORBAN EGY-EGY BYTE-ON binárisan a képpontok fényességei, 
    amik itt az akták számát jelentik (kicsit felszorozva, hogy kontrasztos legyen).
    
  6. Mintaprogram
  7. az aktákat is modellezi külön Akta osztállyal, és az előadáson látott Observer minta segítségével figyel, hogy egy adott aktát melyik hivatalnok, hányszor "nézte" meg.

Utolsó frissítés: 2018-05-05 00.06