7. Micimackó

Czirkos Zoltán · 2019.02.27.

Micimackó – egy régebbi ZH feladat megoldása

Micimackó, a legokosabb mackó a Százholdas Pagonyban, éppen az üres csuprok (Jar) hasznosításán töprengett, amikor rájött, hogy azokban különféle tárgyakat Object) lehet tartani. Így pl. ceruzát (Pencil), térképet (Map) és még mást is, de más éppen nem jutott eszébe. Azt azonban tudta, hogy minden, amit be akar tenni a csuporba, eltérő attribútumokkal rendelkezik. Mackó számára a térképet a neve (std::string), a ceruzát pedig a hossza (int) jellemzi a legjobban.

Segítsen modellezni a feladatot Micimackónak! (Bagoly mesélt valami heterogén kollekcióról, de ezt sajnos Mackó nem értette meg.)

Követelmény, hogy Mackó meg tudja mutatni a csuporba tett tárgyakat és azok attribútumát Robert Gidának. Ehhez a csupor show tagfüggvényét akarja használni, ami a csuporba tett tárgyak nevét és jellemzőit kiírja a paraméterként kapott std::ostream típusú objektumra. Ha a csupor összetörik, akkor a benne levő tárgyak is megsemmisülnek. Egy csuporba maximum 20 tá fér. A modellben megvalósítandó műveleteket az alábbi kódrészlettel mutatjuk be:

Jar *j1 = new Jar; // Ez lesz a csupor

j1->add(new Map("Eszaki-sark")); // Térkép létrehozása és berakása

j1->add(new Pencil(3)); // Ceruza létrehozása és berakása

j1->show(std::cout); // Csupor tartalmának megmutatása

delete j1; // Csupor és tartalmának megsemmisítése

Feltételezheti, hogy a Jar osztályból példányosított objektumot nem akarjuk paraméterként átadni, és értékadás jobb, ill. bal oldalán sem szerepel.

Tervezzen meg és rajzoljon fel egy olyan osztályhierarchiát, ami alkalmas a feladat megvalósítására, és könnyen bővíthető újabb tárgyakkal! Az osztálydiagramban jelölje az adattagok és metódusok láthatóságát is, valamint a virtuális függvényeket is! A string osztályt nem kell lerajzolni, arra típusként hivatkozzon! Ügyeljen a helyes jelölésekre!

Deklarálja C++ nyelven a Jar, Object és Map osztályokat! Csak a Jar osztály konstruktorát, destruktorát, valamint az add() és show() metódusát valósítsa meg!

#include <iostream>
#include <stdexcept>
#include <string>

class Object {
    public:
        virtual void show(std::ostream & os) const = 0;
        virtual ~Object() {}
};


class Map : public Object {
    private:
        std::string name;
    public:
        /* a függvénydefiníciókat nem kérte a feladat */
        Map(std::string name) : name(name) {}
        virtual void show(std::ostream & os) const {
            os << "Map: " << name << std::endl;
        }
};

/* ennek a kódját egyáltalán nem kérte a feladat */
class Pencil : public Object {
    private:
        int length;
    public:
        Pencil(int length) : length(length) {}
        virtual void show(std::ostream & os) const {
            os << "Pencil: " << length << std::endl;
        }
};

class Jar {
    private:
        Object* tomb[20];
        int db;
    public:
        Jar() : db(0) {}
        ~Jar() {
            for (int i = 0; i < db; ++i)
                delete tomb[i];
        }
        void show(std::ostream & os) const {
            for (int i = 0; i < db; ++i)
                tomb[i]->show(os);
        }
        void add(Object *obj) {
            /* kivételkezelést nem kért a feladat */
            if (db == 20) {
                delete obj;
                throw std::out_of_range("megtelt");
            }
            tomb[db] = obj;
            ++db;
        }
};

int main() {
    Jar *j1 = new Jar;
    j1->add(new Map("Eszaki-sark"));
    j1->add(new Pencil(3));
    j1->show(std::cout);
    delete j1;
}