Útmutató a 7.5 laborhoz
A laborfeladat az előadások és a laborok közötti csúszást hivatott kiegyenlíteni. Erre utal a 7.5 elnevezés.
Laborfeladatok megoldásokkal
A feladat célja az osztályokkal, örökléssel, a virtuális tagfüggvényekkel, valamint a heterogén kollekciókkal kapcsolatos ismeretek elmélyítése. A feladat a 7. laborfeladat síkidomokat modellező példáját bővíti tovább. A megoldás során fel kell használni a 7. laborfoglalkozáson elkészített Rajztabla osztályt.
A laborfoglalkozás végén 5 db fájlt kell feltöltenie — nagy részük már majdnem kész van — a Jporta rendszerbe (7.5 önellenőrző feladat), hogy megkapja a labor elvégzéséért járó pontot! Legalább az első öt tesztesetet (ELEKESZULT >= 5) hibátlanul meg kell oldania! A feladatok feltöltésére a laborgyakorlatot követő szombat 06:00-ig van lehetősége.
- Töltse le a laborgyakorlathoz előkészített projektet: https://git.ik.bme.hu/Prog2/labor_peldak/lab_07.5, ami a 7. laboralkalommal már megismert síkidomokat modellező példa módosított változata. Kezdetben a modell csak szakaszt, kört és rajztáblát tartalmaz, amit később bővíteni fogunk. Az új osztályok és funkciók kipróbálását a főprogramban definiált ELKESZULT makróval lehet vezérelni. A megértést segíti a mellékelt osztálydiagram:
- Első feladatként a modellt egy Poligon osztállyal bővítjük. A poligon első csúcsát és színét a konstruktorban kell megadni. Követelmény továbbá, hogy a poligonnak legyen
- size() tagfüggvénye, amivel lekérdezhető, hogy hány csúcspontja van,
- add() tagfüggvénye, amivel újabb pontot lehet adni a poligonhoz,
- rajzol() tagfüggvénye, ami "kirajzolja" a poligont, azaz kiírja az adatait,
- operator[]() tagfüggvénye, amivel lekérdezhető egy adott csúcspont.
Legyen továbbá olyan globális insertere, amivel kiírathatók a poligon adatai a szakasznál és a háromszögnél is alkalmazott formához hasonlóan. Mivel a poligonnak tetszőleges számú csúcspontja lehet, a pontokat dinamikus memóriában fogjuk tárolni. A poligon.h fájlban elkészítettük az osztály deklarációját, ami még nem végleges. A dinamikus memóriaterület közvetlen használata miatt az implicit másoló konstruktor és értékadó operátor nem használható ezért ezeket is meg kell valósítani.
Egészítse ki a poligon.h és poligon.cc fájlokat úgy, hogy az osztály az elvárásoknak megfelelően működjön! Megoldását több lépcsőben tesztelheti az ELKESZULT makró segítségével:- == 1 - Van Poligon osztály, amit önmagában kipróbál, de copy és assign még nincs használva;
- >= 2 - Poligon assign-t is teszteli
- >= 3 - Poligon assign-t és copy-t is teszteli
- A 7. laboralkalommal elkészítette a Rajztabla osztályt. Emelje át megoldását ebbe a projektbe (rajztabla.h, rajztabla,cpp)! Fordítson és teszteljen! A keretprogram ELKESZULT==4 értéknél poligon nélkül fut, ELKESZULT==5 értéknél pedig poligonnal.
- A programunkban dinamikus memóriaterületen hozunk létre az alakzatokat, amelyekre pointerrel hivatkozunk. Ha egy pointerrel hivatkozott objektumról másolatot szeretnénk készíteni a dinamikus memóriában, akkor meg kell hívnunk a másoló konstruktorát valahogy így:
Szakasz* pEredeti = new Szakasz(Pont(20,40), 100, 0, WHITE); Szakasz* pMasolat = new Szakasz(*pEredeti);
Tegyük fel, hogy át szeretnénk másolni egy rajztábla objektumot egy másik rajztáblába. Ekkor nem elegendő a tárolt pointerek lemásolása, a benne tárolt alakzatokról is kell egy-egy másolat (deep copy), ahogy a poligon pontjait is le kellett másolnunk az első feladatban. Igen ám, de a rajztábla objektum alaposztályra mutató pointereket tárol, ezért nem tudjuk, hogy melyik alakzat másoló konstruktorát kell meghívni. Most lenne jó egy virtuális konstruktor, amit a ZH-ban többen fel szoktak találni, de sajnos a C++ nyelvben ilyen nincs. Helyette azonban bevezethetünk egy tagfüggvényt (pl. clone), ami már lehet virtuális és létrehoz egy másolatot saját magából a dinamikus memóriában. A clone használatával már egyszerű a másolat elkészítése. pl:
Alakzat* pEredeti = new Szakasz(Pont(20,40), 100, 0, WHITE); Alakzat* pMasolat = pEredeti->clone();
Módosítsa az alakzat.h fájt úgy, hogy legyen az Alakzat osztálynak egy tisztán virtuális konstans
Alakzat* clone()
tagfüggvénye is! - Valósítsa meg a Szakasz osztály clone() tagfüggvényét a zzakasz.h fájlban! Állítsa az ELKESZULT makró értékét 6-ra! Fortdítson, teszteljen!
- Valósítsa meg a rajztábla értékadó operátorát és a másoló konstruktorát a clone() függvény felhasználásával! Állítsa az ELKESZULT makró értékét 7-re! Fortdítson, teszteljen!Célszerű a másoló konstruktor megvalósítását visszavezetni az értékadó operátorra! Fordítva is lehetséges, de a memtrace nem tudja kezelni a placement new-t, ezért most ezt ne próbálja ki!
- Legyen a poligon is klónozható! Állítsa az ELKESZULT makró értékét 8-ra! Fortdítson, teszteljen!
- Ha elégedett az eredménnyel, akkor töltse fel az elkészített illetve módosított poligon.h, poligon.cpp, szakasz.h, rajztabla.h, rajztabla.cpp fájlokat a Jporta rendszerbe (7.5 labor önellenőrző feladat), hogy megkapja a labor elvégzéséért járó pontot! Legalább ELKESZULT==5 szintig el kell jutnia.
Amennyiben további feladatokat is megoldott, úgy feltöltés előtt a poligon.h fájlban definiálja a ELEKSZULT makrót!
Hogy ne legyen gond a többszörös deifinicióból a lokális környezetében, célszerűen a definiciós rész így nézzen ki:#ifndef POLIGON_H #define POLIGON_H #undef ELKESZULT #define ELKESZULT 7 // A legnagyobb érték, amit szeretne, hogy a jporta teszteljen. ...
-
Valósítsa meg a Rajztabla osztályt a 7. előadáson bemutatott generikus tömb fixArray felhasználásával (https://git.ik.bme.hu/Prog2/eloadas_peldak/ea_07 gen_array2)! Ezt a tárolót a C tömbökkel azonos módon lehet indexelni, ezért a Rajztabla osztály deklarációjában és implementációjában csupán néhány sor változik:
- Include-olni kell a sablont tartalmazó fájlt (gen_array2.hpp).
- Változik a tabla tagváltozó deklarációja.
A gen_array2.hpp fájlt már hozzáadtuk a projekthez, csak használnia kell! Megoldásának teszteléséhez állítsa az ELKESZULT makró értékét 9-re!
Célszerű a másoló konstruktor megvalósítását visszavezetni az értékadó operátorra! Fordítva is lehetséges, de a memtrace nem tudja kezelni a placement new-t, ezért most ezt ne próbálja ki!
Jó munkát!
Szeberényi Imre