Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia



Hasonló dokumentumok
Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

Programozás alapjai II. (8. ea) C++ többszörös öröklés, cast, perzisztencia

Programozás alapjai II. (8. ea) C++ többszörös öröklés, cast, perzisztencia

Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

Osztály és objektum fogalma

Programozás C++ -ban 2007/4

117. AA Megoldó Alfréd AA 117.

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

4. Öröklődés. Programozás II

Származtatási mechanizmus a C++ nyelvben

Programozás II gyakorlat. 4. Öröklődés

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

A C++ öröklés. (Előfeltétel: 12. tétel ismerete)

Programozási alapismeretek :: beadandó feladat. Felhasználói dokumentáció. Molnár Tamás MOTIABT.ELTE

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Programozás II gyakorlat. 6. Polimorfizmus

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

C++ programozási nyelv Struktúrák a C++ nyelvben Gyakorlat

500. CC Megoldó Alfréd CC 500.

Bánsághi Anna

C# osztályok. Krizsán Zoltán

Bevezetés a programozásba 2

0.1. Mi az a standard be- és kimenet? A két mintafeladat leírása

Magas szintű programozási nyelvek 2 Előadás jegyzet

Programozás alapjai II. (4. ea) C++

Objektumorientált programozás C# nyelven

Programozás C++ -ban

Géptermi zh-írás forgatókönyve

Bevezetés a C++ programozási nyelvbe

Objektumorientált programozás C# nyelven

Programozás II. 4. Dr. Iványi Péter

Programozás C++ -ban

Bánsághi Anna

500. AA Megoldó Alfréd AA 500.

Bevezetés a C++ programozásba

PHP II. WEB technológiák. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) PHP II / 19

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

1. Alapok. Programozás II

3. Osztályok II. Programozás II

Elemi Alkalmazások Fejlesztése II.

Programozás 5. Dr. Iványi Péter

Objektumok inicializálása

C++ programozási nyelv

Programozás alapjai II. (6. ea) C++

STL. Algoritmus. Iterátor. Tároló. Elsődleges komponensek: Tárolók Algoritmusok Bejárók

osztályok kapcsolata Származtatatás C++ Izsó Tamás március 19. Izsó Tamás Származtatatás/ 1

C++ programozási nyelv Konstruktorok-destruktorok

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

128. AA Megoldó Alfréd AA 128.

Programozás alapjai II. (5. ea) C++

1.AA MEGOLDÓ BERCI AA 1.

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás


Programozás alapjai II. (6. ea) C++

Programozás alapjai II. (6. ea) C++

503.AA Megoldo Arisztid 503.A

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

3. Gyakorlat Ismerkedés a Java nyelvvel

Programozás alapjai II. (4. ea) C++

Programozás alapjai II. (4. ea) C++

PHP5 Új generáció (2. rész)

Pénzügyi algoritmusok

0.2.1 Operátorok túlterhelése (műveletek definiálhatók felhaszn. típusokra) Kutya. Eb1. Eb2. Név (txt): Rex. Blöki. Német juhász 3

Események C#-ban Krizsán Zoltán iit

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

AA MEGOLDÓ ALADÁR AA

Emlékeztető: a fordítás lépései. Szimbólumtábla-kezelés. Információáramlás. Információáramlás. Információáramlás.

Bevezetés a programozásba Előadás: Tagfüggvények, osztály, objektum

1000.AA Megoldo Alfréd 1000.A

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

Globális operátor overloading

ISA szimulátor objektum-orientált modell (C++)

Java és web programozás

Programozás alapjai II. (2. ea) C++

Információs Technológia

Visual C++ osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés.

OOP #14 (referencia-elv)

Körkörös listák. fej. utolsó. utolsó. fej

Információs Technológia

Bevezetés a C programozási nyelvbe. Az Általános Informatikai Tanszék C nyelvi kódolási szabványa

Objektumorientált programozás C# nyelven III.

Programozás II gyakorlat. 8. Operátor túlterhelés

Bevezetés a programozásba Előadás: A const

Osztályok. 4. gyakorlat

Programozás alapjai II. (2. ea) C++

Programozás alapjai II. (2. ea) C++

Programozás alapjai II. (3. ea) C++ Programfejlesztés. Néhány programozási módszer. Feladatanalízis. Modellezés Tervezés. Implementáció (programozás)

Objektumorientált programozás C# nyelven

SZERVER OLDALI JAVASCRIPT. 3. hét Javascript nyelvi elemek

Programozás. Osztályok, Származtatott osztályok. Fodor Attila

Programozás BMEKOKAA146. Dr. Bécsi Tamás 7. előadás

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

Programozás II. 2. Dr. Iványi Péter

Programozás II gyakorlat. 7. Példák a polimorfizmus alkalmazásaira

Java és web programozás

PROGRAMOZÁSI NYELVEK - CPP. GYAKORLAT JEGYZET

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

Átírás:

Öröklés ism. Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia Szeberényi Imre BME IIT <szebi@iit.bme.hu> Egy osztályból olyan újabb osztályokat származtatunk, amelyek rendelkeznek az eredeti osztályban már definiált tulajdonságokkal, viselkedéssel. Analitikus - Korlátozó Egyszeres - Többszörös M Ű E G Y T E M 1 7 8 2 C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -1- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -2- Többszörös öröklés Ha két osztály merőben különbözik, de mindkettőben valamit meg kell valósítani a másik számára. Az új osztálynak többféle arcot kell mutatnia (mutatókonverzió). Sokszor kiváltható barát függvényekkel, de nem a legjobb megoldás. Objektum és a környezet (pl. grafikus) kapcsolata. Többszörös öröklés/2 Két vagy több bázisosztályból származtatunk. Több OO nyelv nem támogatja, mert bonyolult implementálni. Ezekben a nyelvekben interfésszel váltják ki a többszörös öröklést. Leggyakrabban grafikus interfész és a modell kapcsolatánál használjuk. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -3- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -4- Példa: Nyomógomb és callback fv. A grafikus rendszer kezeli a felhasználói eseményeket. Ha megnyomják (áthaladnak fölötte, elengedik, stb.), meghívja az alkalmazás megfelelő függvényét (callback), amit korábban az alkalmazás közölt a gombbal. Példa: Kapcsoló Gombnyomásra ki-be lehessen kapcsolni A (grafikus) felhasználói felületen megvalósított gomb megkap minden felhasználói inputot. Amikor azt kapja, hogy "megnyomták", akkor szól a kapcsolónak, amit valójában nem is ismer, a probléma megoldható virtuális függvénnyel, de... A kapcsolót a felhasználói felületből kell származtatni? A felhasználói felületnek semmi köze a funkcionalitáshoz! C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -5- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -6-1

Kapcsoló a grafikus felületből? Kapcsoló többszörös örökléssel Gomb callback() Kapcsoló Virtuális fv. callback() Megvalósítás A grafikának semmi köze a funkcionalitáshoz! Eddig úgy tudtuk, hogy a Kapcsoló a Drót-ból származik! A grafikus felülettől függ a működés? Drót végpontok Funkciójában ebből származik GombCallback callback() Kapcsoló callback() Megvalósítás Gomb cb.obj.ref. Virtuális fv. Könnyű ilyenné konvertálni C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -7- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -8- Kapcsoló megvalósítása class GombCallback { // callback funkcióhoz virtual void callback() = 0; // virtuális cb. függvény class Gomb { // felhasználói felület objektuma GombCallback &cb; // objektum referencia Gomb (GombCallback &t) :cb(t) {// referencia inic. void Nyom() { cb.callback(); // megnyomták... C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -9- Kapcsoló megvalósítása/2 class Kapcsolo :public Drot, public GombCallback { int be; // állapot Az osztály kompatibilis a GombCallback void ki(); osztállyal, amin keresztül a Gomb osztály void be(); eléri a callback függvényt.... void callback() { if (be) ki(); else be(); // callback Kapcsolo k1; Gomb g1(k1); class Gomb { GombCallback &cb; Gomb (GombCallback &t) :cb(t) { void Nyom() { cb.callback(); C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -10- Töbsz. öröklés + fv. overload Többszörös öröklés problémái struct A { void f() { void f(int) { sturct B { void f(double){ Melyik f? struct AB : public A, public B { using A::f; using B::f; void f() { f(1); f(1.2);... AB ab; ab.f(); ab.f(5); ab.f(6.3); Többszörös öröklés különös figyelmet igényel, ha előfordulhat, hogy egy alaposztály különböző leszármazottjai "összetalálkoznak". Ekkor ún. rombusz v. "diamond" struktúra alakul ki. Példa: irodai hierarchia Feltételezés: A többszörös öröklésnél merőben eltérőek az alaposztályok, az azonos ű függvények más-más funkciót látnak el. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -11- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -12-2

Csop.vez. Irodai hierarchia Alkalmazott név, fizetés Hat.idejű.cs.v. Hat.idejű idő C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -13- Irodai hierarchia /2 class Alkalmazott { protected: char [20]; // név double ; // fizetés Alkalmazott(char *n, double fiz); class CsopVez :public Alkalmazott { csop_t ; // azon. CsopVez(char *n, double f, csop_t cs) :Alkalmazott(n, f), (cs) { C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -14- Irodai hierarchia /3 class HatIdeju :public Alkalmazott { time_t ido; // szerződése lejár ekkor HatIdeju(char *n, double f, time_t t) :Alkalmazott(n, f), ido(t) { class HatIdCsV :public CsopVez, public HatIdeju { HatIdCsV(char* n, double f, csop_t cs, time_t t) :CsopVez(n, f, cs), HatIdeju(n, f, t) { Két e és két fizetése van? C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -15- Elérhetők ezek a mezők? class HatIdCsV :public CsopVez, public HatIdeju { HatIdCsV(char* n, double f, csop_t cs, time_t) :CsopVez(n, f, cs), HatIdeju(n, f, t) { void Kiir() { cout << CsopVez :: << endl; cout << HatIdeju :: << endl; A scope operátorral kiválasztható, tehát önmagában ez még nem lenne baj, de baj lehet belőle. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -16- Memóriakép Miből fakad a probéma? struct CsopVez struct Alkalmazott struct HatIdCsV ido struct HatIdeju ido Többszörös elérés az öröklési gráfon. Miért nem vonja össze a fordító? A ek ütközése az öröklés megismert szabályai alapján még nem jelent bajt. Lehet hogy szándékos az ütközés. Automatikus összevonás esetén a kompatibilitás veszélybe kerülhet. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -17- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -18-3

Megoldás: Virtuális alaposztály class CsopVez :virtual public Alkalmazott {... Csak az öröklési lánc legvégén hívódik meg alaposztály konstruktora (explicit esetben is). CsopVez(char *n, double f, csop_t cs) :Alkalmazott(n, f),// csak lánc végén (cs) { class HatIdeju :virtual public Alkalmazott{... class HatIdCsV :public CsopVez, public HatIdeju { HatIdCsV(char* n, double f, csop_t cs, time_t t) :Alkalmazott (n, f), // csak ha a lánc vége CsopVez(NULL, 0, cs), // tudjuk, hogy nem HatIdeju(NULL, 0, t) { // hívódik, ezért lehet NULL C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -19- Virtuális alaposztály 1. Alaposztály adattagjai nem épülnek be a származtatott osztály adattagjaiba. A virtuális függvényekhez hasonlóan indirekt elérésűek lesznek. 2. Az alaposztály konstruktorát nem az első származtatott osztály konstruktora fogja hívni, hanem az öröklési lánc legvégén szereplő osztály konstruktora. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -20- Memóriakép virt. alaposztállyal struct CsopVez &Alkalmazott struct Alkalmazott virtual struct HatIdCsV &Alkalmazott idő &Alkalmazott struct HatIdeju idő &Alkalmazott C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -21- Konstruktor feladatai Öröklési lánc végén hívja a virtuális alaposztályok konstruktorait. Hívja a közvetlen, nem virtuális alaposztályok konstruktorait. Létrehozza a saját részt: beállítja a virtuális alaposztály mutatóit beállítja a virtuális függvények mutatóit hívja a tartalmazott objektumok konstruktorait végrehajtja a programozott törzset C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -22- Destruktor feladatai Megszünteti a saját részt: végrehajtja a programozott törzset tartalmazott objektumok destruktorainak hívása virtuális függvénymutatók visszaállítása virtuális alaposztály mutatóinak visszaállítása Hívja a közvetlen, nem virtuális alaposztályok destruktorait. Öröklési lánc végén hívja a virtuális alaposztályok destruktorait. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -23- Irodai példa újból class Alkalmazott {... class HatIdeju :virtual public Alkalmazott{... class CsopVez :virtual public Alkalmazott {... class HatIdCsV :public CsopVez, public HatIdeju {... class HatIdCsVH :public HatIdCsV {... Melyik konstruktor hívja az Alkalmazott konstruktorát? Alkalmazott melos("lusta Dick", 100); // Alkalmazott HatIdeju grabo("grabovszki", 300); // HatIdeju CsopVez fonok("mr. Gatto ", 5000); // CsopVez HatIdCsV gore("mr. Tejfel", 3000); // HatIdCsV HatIdCsVH ("Safranek", 500); // HatIdCsVH Aki a lánc végen van. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -24-4

És, ha nem lenne virtuális? class Alkalmazott {... class HatIdeju :public Alkalmazott{... class CsopVez :public Alkalmazott {... class HatIdCsV :public CsopVez, public HatIdeju {... class HatIdCsVH :public HatIdCsV {... Melyik konstruktor hívja az Alkalmazott konstruktorát? Alkalmazott melos("lusta Dick", 100); // Alkalmazott HatIdeju grabo("grabovszki", 300); // HatIdeju CsopVez fonok("mr. Gatto ", 5000); // CsopVez HatIdCsV gore("mr. Tejfel", 3000); // CsopVez, HatIdeju HatIdCsVH ("Safranek", 500); // CsopVez, HatIdeju Aki az első a láncban. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -25- Elkerülhető a többsz. öröklés? Egyes OO nyelvekben nincs többszörös öröklés, de van helyette interfész, amivel pótolható a hiánya. C++ -ban ilyen nincs, ezért teljesen nem kerülhető el. Biztosan nem kerülhető el, ha mindkét osztály "arcát" mutatni kell (pl. ny.gomb) mindkét osztályt valamiért alaposztállyá kell konvertálni (upcast) C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -26- Mutatókonverzió újra Származtatott osztály a kompatibilitás révén könnyen konvertálható alaposztályra. Ez hívjuk "upcast"-nak. Leggyakrabban pointereket konvertálunk (heterogén gyűjtemény). Többszörös öröklésnél a konverzió nagy figyelmet igényel. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -27- Mut. konv. többszörös öröklésnél Base1 * pb1 alap1 MulDer md; Base2 * pb2 alap2 memóriakép kompatibilis új rész class Base1 {... class Base2 {... class MulDer : public Base1, public Base2 {... MulDer md; Base1 * pb1 = &md; Base2 * pb2 = &md; // mutató értékmódosítás! C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -28- Konv. többsz. öröklésnél szárm.-ra MulDer * pmd alap1 alap2 Base2 base2 új rész Base2 base2; MulDer *pmd = (MulDer *) &base2; // mutató értékmódosítás! // nem létező adatmezőket és üzeneteket el lehet érni // veszély: explicit konverzió C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -29- Megbocsátható down cast Néha előfordul, hogy tudjuk, hogy egy adott mutató egy származtatott osztályból származik, de valamiért alappá konvertáltuk (pl. heterogén kollekció) Ekkor biztonságos a dinamic_cast használata, ami futási időben történik. Ha A* tipusú, akkor OK, egyébként NULL MulDer A; Base1 *p = &a; MulDer *pa = dynamic_cast<a*>(p); C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -30-5

cast átértékelése C: (típus) Explicit típuskonverziót végez. Használata körültekintést igényel. C programokban leginkább a malloc környékén fordul elő joggal. Eredménye nem lvalue. C++: Sokkal többször és sokkal több okból fordulhat elő joggal. A veszélyek csökkentésére több változata létezik: (dynamic_cast, static_cast, const_cast, reinterpret_cast, (tipus), tipus()) dynamic_cast szintaxis: dynamic_cast<t>(v) v alaposztályra hivatkozik, vagy pointer T származtatott osztályra hivatkozik, vagy void pointer struct A { virtual ~A(){ struct B :A { struct C :A { NULL polimorf A* apb = new B; A* apc = new C; B* bp1 = dynamic_cast<b*>(apb); B* bp2 = dynamic_cast<b*>(apc); C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -31- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -32- static_cast szintaxis: static_cast<t>(v) v alaposztályra hivatkozik, vagy pointer T származtatott osztályra hivatkozik, vagy void pointer struct A { struct B :A { struct C :A { A* apb = new B; A* apc = new C; B* bp1 = static_cast<b*>(apa); B* bp2 = static_cast<b*>(apc); Fordítási időben történik, nincs futás idejű ellenőrzés! Jelzi, ami fordítási időben tilos. (pl. int* -> B*) C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -33- const_cast szintaxis: const_cast<t>(v) Csak a const vagy a volatile minősítő eltávolítására vagy előírására használható. const int a = 10; const int* b = &a; int* c = const_cast<int*>(b); *c = 30; //nincs ford.hiba.!!nem definit!! int a1 = 40; const int* b1 = &a1; int* c1 = const_cast<int*>(b1); *c1 = 50; // minden OK, mert a1 nem konst. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -34- reinterpret_cast szintaxis: reinterpret_cast<t>(v) Ellenőrzés és változtatás nélkül átalakítja v-t a megadott típusúvá. Igen veszélyes, de legalább könnyen felismerhető a forrásban. A const ill. volatile minősítés nem módosítható vele. struct B { B* p = new B; long l = reinterpret_cast<long>(p); (típus), típus( ) A C stílusú cast mellett használható még az úgyezett funkció stílusú cast is. Lehetőleg az úgyezett esített (dynamic_cast, static_cast, const_cast, reinterpret_cast) változatokat kell használni. Használatukkal a konverziókból adódó problémák sokkar könnyebben felfedezhetők. int i, j; double d; d = (double)i/j; d = double(i)/j; // funkció stílusú cast C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -35- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -36-6

Obj Attr. Perzisztencia Obj Attr. A perzisztens objektumok állapota elmenthető és visszatölthető egy későbbi időben, esetleg másik gépen létrehozott objektumba. A visszatöltött objektum "folytatja" a működést. Perzisztencia/2 Az objektum a saját állapotát képes kiírni egy adatfolyamba serializáció Az objektum a saját állapotát képes beolvasni egy adatfolyamból deserializáció Szempont lehet a hordozható külső formátum is. Ez különösen fontos elosztott rendszereknél. A perzisztenciát gyakran többszörös örökléssel oldják meg. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -37- C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -38- Perzisztencia örökléssel I./1 class Serialize { int size; // kírandó adat mérete Serialize(int s) :size(s) { // méret beállítása void write(ostream& os) const { os.write((char *)this, size); // kiírás void read(istream& is) const { is.read((char *)this, size); // beolvasás C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -39- Perzisztencia örökléssel I./2 class Complex { Képes kiírni ill. visszatölteni double re, im;... class PComplex : public Serialize, public Complex { PComplex(double re, double im) : Complex(re, im), Serialize(sizeof(PComplex)) { Származtatott mérete int main() { ofstream f1("f1.dat"); PComplex k1(1, 8); k1.write(f1); return 0; int main() { ifstream f1("f1.dat"); PComplex k1; k1.read(f1); return 0; C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -40- A sorrendre érzékeny! class PComplex : public Serialize, public Complex {... Complex Serializable re size im write((char*)this,size) PComplex:: this Serialize:: this Complex:: this PComplex size re im class PComplex : public Complex, public Serialize {... C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -41- re im size Problémák Pointerek visszatöltésének nincs értelme. Veszélyes a kód: A öröklés sorrendjére érzékeny. A Serialize osztálynak kell elsőnek szerepelni. Mi van a virtuális függvények mutatóival? Külső reprezentáció nem hordozható. Ötletnek nem rossz, de a gyakorlatban használhatatlan! C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -42-7

Van megoldás? C++-ban nehéz automatizálni a serializációt. Néhány könyvtár ad támogatást (pl. boost, MFC, s11n) Fapados, de működő megoldás: magára az objektumra kell bízni az adatfolyammá történő alakítást ill. visszaalakítást. Kellő körültekintéssel el kell készíteni a megfelelő virtuális függvényeket. C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -43- Használható megoldás class Serializable { virtual void write(ostream& os) const = 0; // kiíró virtual void read(istream& is) = 0; // beolvasó virtual ~Serializable() { // ne legyen probléma az upcast class String { protected: // hogy hozzáférjen a származtatott char *p; // van dinamikus adattag int len; String(char *s = "" ) { len = strlen(s); p = new char[len+1]; strcpy(p, s);... C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -44- Használható megoldás class PString : public Serializable, public String { PString(char *p = "") : String(p) { void write(ostream& os) const { os << len << ' '; // separator os.write(p, len); // a string kiírása void read(istream& is) { delete[] p; (is >> len).ignore(1); // len beolv., eldobjuk a szepart. p = new char [len+1];// új terület kell is.read(p, len); // len db karaktert olvasunk p[len] = 0; // lezáró nulla C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -45- Kérdések, megjegyzések Fontos, hogy a read() metódus pontos tükörképe legyen a write()-nak. Fontos a megfelelő reprezentáció kiválasztása. Kézenfekvő mindent szöveggé alakítani. Ekkor numerikus kiírások után kell szeparátor, amit a beolvasáskor el kell dobni. Pointerek és referenciák kezelése külön figyelmet igényel. Miért kell többszörös öröklés? ha módosítható az osztály megoldható töbsz. nélkül ha nincs kezünkben az osztály csak ez a lehetőség C++ programozási nyelv BME-IIT Sz.I. 2011.04.12. -46-8