Kisházi gondolatok
Olvasd el, próbáld ki, értsd meg, de nem kell javítani a feltöltött háziban.
A múlt heti háziban egy absztrakt ősből örökítettünk egy komplex és egy string osztályt. Miért teszünk ilyet? Leginkább azért, mert heterogén kollekcióban együtt szeretnénk tárolni a kétféle objektumot. Például egy áramkörszimulátorban bizonyos elemek leírására elegendő egy-két valós esetleg komplex érték (R,L,C,Z), ellenben egy diódát vagy tranzisztort a típusjelével hivatkozunk (amihez külön file tartalmazza a modellparamétereket).Miért kell legyen destruktor az ősosztályban? Miért kell virtuális legyen a destruktor az ősosztályban?
A háziban egy absztrakt ősből örökítettünk egy stringet:szo
. Ez dinamikus adattagot tartalmaz, baj lenne, ha nem futna le a destruktora.A kisháziban ez nem áll fenn, heterogén kollekció jellegű tárolásnál (ami ilyen örökítéseknél szokásos) viszont gond lehet.
Próbáljuk ki az alábbi kódot háromféleképpen.
- Így ahogy van, bemásolva egy .cpp fileba, ilyenkor az ős destruktorát a rendszer adja, épp csak kiírás nincs benne.
- Vegyük ki kommentből az első dtort. Ugyanaz, mint az előző eset, de most van kiírás is.
- Most vegyük ki kommentből a második dtort (az első vissza//). Most virtuális a destruktorunk.
#include <iostream> class os { public: os() { } // ~os() { std::cout << "Destroy OS" << std::endl; } //ez ugyanaz, mint amikor nem irunk dtort // virtual ~os() { std::cout << "Destroy OS" << std::endl; } // pure virtual (=0) nem jo! }; class szo : public os { // itt van din. adattag, igy fontos a dtor public: szo() { } ~szo() { std::cout << "Destroy SZO" << std::endl; } // ha ezt nem latjuk: mem leak! }; int main() { os* s = new szo; //heterogen kollekcioban igy taroljuk, emlekezz: equipment delete s; //delete (szo*)s; //ez mindenkepp mukodne szo-ra, de mas leszarmazottra meg nem!... return 0; }
Órai dolgok
- Az órán a 11. aut-os konzerv 1. feladatát oldjuk meg: Vector (tömb) osztálysablont készítünk.
-
Ha a fenti feladattal készen vagyunk, nézzük meg az alábbi kódot. Elég primitív sablon, de mit mond rá a compiler? Hány osztályt készített a sablonból az alábbi tesztelő fordításához?
/* * Ez a program a sablon metaprogramozást mutatja be. A factorial osztály sablon paramétere egy szám, * aminek a faktoriálisa az osztály publikus konstansába (value) kerül bele fordítási idő alatt. * Az osztály definíciója rekurzív -- a value kiszámításához szükség van az (N-1)-gyel példányosított * factorial value értékére. A rekurzió báziskritériuma (leállítása) specializációval történik: (N=0)-ra * specializáljuk a factorial osztályt, így az (N=1)-gyel példányosított factorial már nem fogja előírni * új sablonosztály létrehozását, hanem a már létező factorial<0>::value-t fogja felhasználni. * * Annak érdekében, hogy láthatóvá váljon a tény, hogy az algoritmus (jelen esetben a faktoriális számítás) * !fordítási időben! kerül végrehajtásra, a programban egy olyan szintaktikai hiba van, ami miatt nem * fordítható le, azonban a fordító által adott hibaüzenet tartalmazza a számítás eredményét. * * A hibát úgy állítjuk elő, hogy megpróbálunk egy nem osztály objektum tagjára hivatkozni. A kérdéses * nem osztály objektum a main()-ben létrehozott tömb, aminek a méretét faktoriális számító algoritmusunkkal * adjuk meg. A fordítói hibaüzenetben az áll, hogy a nem osztály objektum egy char tömb, aminek megadja * a méretét is, ami pontosan a kérdéses faktoriális. */ template <unsigned N> class factorial { public: const static unsigned value = factorial<N - 1>::value * N; }; template <> class factorial<0> { public: const static unsigned value = 1; }; int main() { char s[factorial<8>::value]; s.x; //ez fordítási hibát fog okozni return 0; }
Jövő órán kiszh lesz.
11. Házi feladat.
Készítsünk halmazokból álló tömböt!-
Vegyük elõ a 6. heti halmaz osztályunkat. (A hf szerint bõvítettet.)
Készítsünk belõle osztálysablont! (Az alábbi feladatok megvalósításához szükségtelen elemeket megjegyzésbe tehetjük, de ne töröljük!)
A tároló osztály átalakításakor figyeljünk oda: amit lehet/kell, azt most már tegyük const-tá.
-
Ügyeljünk arra, hogy a
friend
függvényünk globális, nem tagfüggvény, az osztályon belül csak a barátságát deklaráljuk, definiálni nem itt kell! - Vegyük elő az órai tömb osztálysablont.
-
Készítsünk kipróbáló modult, melyben
-
legyen egy egészekbõl álló halmazokat tartalmazó tömbünk:
Vector < Halmaz < int > > t;
. - A tömb kezdetben üres.
- Ezután adjunk hozzá egy üreshalmazt, és két (nem dinamikus) egész tömbből előállított halmazt.
-
Végül adjuk hozzá a tömb második és harmadik halmazának metszetét valamint unióját, és írjuk ki a tömböt:
std::cout << t;
.
-
legyen egy egészekbõl álló halmazokat tartalmazó tömbünk:
- A program tagolása a sablonoknál megszokott: minden a két .h-ban, csak a tesztelő .cpp.