String osztály létrehozása

Slides:



Advertisements
Hasonló előadás
C# nyelvi áttekintő A „Programozás C# nyelven (Illés Zoltán)”
Advertisements

Osztály leszármaztatás
C++ programozási nyelv Gyakorlat hét
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
8. előadás (2005. április 19.) Pozicionálás fájlban (folyt.) I/O mechanizmus váltás Hibakezelő függvények Változók tárolási osztályai Parancssor-argumentumok.
Öröklődés 2..
© Kozsik Tamás Tömbök, kollekciók és egyéb alaposztályok.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Programozás alapjai.
Dinamikus tömbök.
Csala Péter ANDN #4. 2 Tartalom  C# - ban előre definiált típusok  Változók  Változókkal műveletek  Elágazás  Ciklus.
Sztringek.
Bevezetés a Java programozásba
5. előadás (2005. március 22.) Függvények definíciója, deklarációja, hívása Enumerációs adattípus 1.
4. előadás (2005. március 8.) Pointerek Pointer aritmetika
Osztályok Garbage collection.  általában minden osztálynak vannak adattagjai és/vagy metódusai ◦ adattagok megadása:  [láthatóság] [static] [final]
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 7. Gyakorlat Operator overloading.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 5. Gyakorlat Öröklődés, virtuális függvények,
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Tömbök ismétlés Osztályok Java-ban Garbage collection
Függvények, mutatók Csernoch Mária.
Mutatók, tömbök, függvények
Borland C/C++ mintapéldák struktúrákra. 1. példa /* Egyszerû példa a struktúrák használatára */ #include #define SIZE 5 struct szemely { char nev[26];
A Java programozási nyelvSoós Sándor 1/17 Java programozási nyelv 4. rész – Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
Java programozási nyelv 3. rész – Osztályok I.
A C++ programozási nyelvSoós Sándor 1/10 C++ programozási nyelv Gyakorlat - 5. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
A C++ programozási nyelvSoós Sándor 1/15 C++ programozási nyelv Gyakorlat hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
C# tagfüggvények.
C# tagfüggvények.
C++ Alapok, első óra Elemi típusok Vezérlési szerkezetek
6. előadás Parametrikus polimorfizmus. Generikus programozás. Az Ada sablonok.
Ficsor Lajos Template-ek CPP8/ 1 Template-ek. Ficsor Lajos Template-ek CPP8/ 2 A template fogalma Kiindulási probléma: tetszőleges típusokon kellene ugyanolyan.
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
Java programozási nyelv Metódusok
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 4. Gyakorlat Függvény paraméterek, dinamikus.
Objektum orientált programozás
1 Objektum orientált programozás Öröklődés: többszörös öröklődés, konstruktorok, destruktorok, overloading Nagy Szilvia.
Programozás III OOP ALAPOK.
Programozás III KOLLEKCIÓK.
Függvények a C nyelvben 1 Függvényeket a következő esetekben szokás írni: Ha ugyanazt a tevékenységet többször is el kell végeznünk ugyanolyan típusú,
Ficsor Lajos CPP2 / 1 Származtatási mechanizmus a C++ nyelvben Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék.
CUDA C/C++ programozás CUDA C bevezetés A segédanyag készítése a TÁMOP A/ Nemzeti Kiválóság Program című kiemelt projekt keretében.
Ficsor Lajos A C++ programozási nyelv I. CPP1/ 1 Osztály és objektum fogalma.
Típuskonverzió a C++ nyelvben
A 2. géptermi beszámoló VBA anyagának összefoglalása
Ficsor Lajos Objektumok inicializálása CPP4 / 1 Objektumok inicializálása Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék.
Objektum orientált programozás 4. Mutatók, típusok és struktúrák Nagy Szilvia.
Függvények, mutatók Csernoch Mária. Függvények függvény definíciója az értelmezési tartomány tetszőleges eleméhez hozzárendel egy értéket –függvény helyettesítési.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 4. gyakorlat.
Függvények, mutatók Csernoch Mária. Függvények függvény definíciója az értelmezési tartomány tetszőleges eleméhez hozzárendel egy értéket –függvény helyettesítési.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
LA C++ programozási nyelv Alkalmazott Informatikai Tanszék MŰSZAKI INFORMATIKA dr.Dudás László 19./0. lRokonok, barátok lÚj műveletek hozzárendelése az.
a programegységek között
Programozási nyelvek típusossága.
A C++ programozási nyelv
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Öröklődés Objektumok közötti speciális kapcsolat.
Konverziós operátorok
Az objektum-orientáltság
Feladat Készítsünk programot, amely ciklikusan egy egyenest forgat 8 fokonként, mialatt 3 db vektort mozgat és forgat 5, 6 ill 7 fokonként, és kijelzi.
Függvénysablonok használata
Osztály fogalom Új fogalom: osztály (class).
Előadás másolata:

String osztály létrehozása

Sztring osztály létrehozása   Feladat: Készítsünk olyan programot, amely sztringeket képes létrehozni, valamint azokkal műveleteket végezni. Az igényelt műveletek: sztring egyes karaktereinek írása illetve olvasása, sztringek másolása, összefűzése, összehasonlítása és nyomtatása.˙

Objektumokat leíró táblázat:

Műveletek: tipikusan operátorokkal célszerű reprezentálni őket. Attribútumok: a specifikáció nem ad támpontot. Régebbi tapasztalatainkra támaszkodjunk! Figyelembe veendő szempontok: tárolt karakterek száma előre nem ismert és az objektum élete során is változó. Kézenfekvő a karakterek helyét a dinamikus memóriából lefoglalni, az attribútumok között csak az adminisztrációhoz szükséges változókat tartjuk nyilván. Ilyen változó: karaktersorozat kezdőcíme a heap-en (pstring) a sztring aktuális hossza (size).

size: redundáns adat, hiszen számolható size: redundáns adat, hiszen számolható Fennáll az inkonzisztencia veszélye. Hatékonyság miatt azonban célszerű!

Sztring osztály definíciója class String { char *pstring; int size; public: String (char* s = ““) { //String default konstruktor pstring = new char [ size = strlen (s) + 1 ]; strcpy(pstring,s); } ~String ( ) { delete [ ] pstring ; } char& operator [ ] (int i ) { return pstring [ i ]; } String operator+( String& s ) { char *psum = new char [size + s.size - 1 ]; strcpy (psum, pstring ); strcat (psum, s.pstring) ; String sum (psum ); delete psum; return sum; } };

A konstruktor feladata - az átadott sztring alapján a szükséges terület lefoglalása a heap-en - a sztring heap-re másolása - az adminisztrációs adattagok kitöltése A konstruktordefiníció tartalmazza az alapértelmezésű (paramétert nem igénylő konstruktort is ( alapértelmezésű argumentuma miatt)  

Destruktor feladata A heap-en lefoglalt terület felszabadítása.

Az index operátor Feladata: használatával egy karaktert lekérdezhetünk, illetve megváltoztathatunk. Fontos! Referencia típus· a visszatérési értéke.

main() {. char c;. String s (“én string vagyok” );. c = s [ 3 ]; main() { char c; String s (“én string vagyok” ); c = s [ 3 ]; // c=s.operator[] (3); c=pstring[3]; s[ 2 ] = ‘a’; // s.operator[] (2)=‘a’; pstring[2]=‘a’; } //delete [] pstring

Az index operátor c= s[ 3 ]; az operátor átdefiniálás szerint ekvivalens a c=s.operator[](3) utasítással, ami viszont a String::operator[] törzse szerint a c-hez a string[3]-t rendeli hozzá. s[2] = ‘a’ viszont a s.operator [](2) = ‘a’-nak felel meg. Ez az értékadás bal oldalán függvényhívást jelent. C-ben nem megengedett. Nem referencia típusú visszatérési érték esetén visszaadná a sztring 2-ik karakterének értékét. Referencia típus miatt az s.operator [](2) a pstring[2] helyettesítő neve, így értéke meg is változtatható  

Referencia típus Amennyiben olyan függvényt írunk, amelyet balértékként (az értékadás bal oldalán) akarunk használni, akkor annak referenciát kell visszaadnia. Az index operátor szinte mindig referencia típusú!  

Összeadás operátor - Ideiglenesen foglalunk egy karaktertömböt - előállítjuk az összefűzött sztringet (az -ideiglenesen foglalt tömbben) - megkonstruáljuk a visszatérési érték String típusú objektumát. - az ideiglenes tömböt felszabadítjuk - visszatérünk és visszatérési értékünk a létrehozott objektum.

Problémák : értékadásnál Tekintsük a következő programrészletet: { String s1 (“baj”), s2 ("van!"); s2 = s1; } Az értékadás operátor (=) az adattagokat egy az egyben másolja (bitmásolás)

Bitmásolás most nem jó! s2.size is 4 értékű lesz “baj”-ra két mutató is mutat, míg “van”-ra egy sem. ha s1 változik, akkor s2 is változik a “baj” kezdőcímére két delete-t hajt végre a program a destruktor meghívásakor, míg a “van”-t senki sem szabadítja fel.˙  

Értékadó operátor átdefiniálása class String { ..... void operator=(String& ); }; void String :: operator=(String& s) { delete pstring; pstring = new char [size = s.size]; strcpy (pstring, s.pstring); }

További problémák //nem lehet s1=s2=s3; s1=s2=s3 nem megengedett Ez ekvivalens lenne a következővel: s1.operator=(s2.operator=(s3)); s1.operator= bemenő argumentuma az s2.operator=(s3) visszatérési értéke, ami viszont void, holott String& kellene, hogy legyen. Megoldás: visszatérési érték megváltoztatása 

Még további probléma   s=s; értékadás hibásan működik. Ekkor ugyanis az s.operator= referenciaként megkapja s-t, azaz önmagát, amelyhez tartozó heap területet felszabadítja, majd innen másol.  Megoldás lehet, hogy megvizsgáljuk, hogy a referenciaként átadott objektum címe megegyezik-e a célobjektum címével.

Javított változat class String { ..... String& operator=(String& ); //s1=s2=s3; lehet }; String& String :: operator=(String& s) { if (this != &s ) { //s = s ; miatt delete pstring; pstring = new char [size = s.size]; strcpy (pstring, spstring); } return *this; }

Problémák 2. Értékadással kapcsolatos problémák megoldódtak. Kivéve: ha =-et használunk valamely objektumpéldány kezdőértékkel való ellátására.: { String s1(“baj”); ......... String s2 = s1; }

Az itt szereplő = jel nem az értékadás, hanem az inicializálás műveletét jelöli. Inicializálás alapértelmezése: bitenkénti másolás. (Ha nem lenne különbég a kettő között és az operator= mindkét esetben felülbírálja a műveletet, akkor a String s2 = s1 utasításból kialakuló s2.operator=(s1) függvényhívás azzal indulna, hogy a delete s2.pstring utasítást hajtaná végre (Pedig a pstring még nincs is inicializálva! Az operator= fv-ben nem tudjuk eldönteni, hogy volt-e már inicializálva egy objektum, vagy sem).  

Problémák 2. Beláttuk, - hogy jó, ha nem hívja meg az operator= függvényt - rossz, hogy az inicializálás alapértelmezése szerinti műveletet hajtja végre (bitmásolás) Megoldás “inicializáló operátort” az ún. másoló konstruktort kell átdefiniálni.  

Másoló konstruktor Másoló konstruktor - az osztály nevét kapja - a másoló jellegét az adja, hogy ugyanolyan típusú objektummal kívánjuk inicializálni, ezért az argumentuma is ezen osztály referenciája - egy x osztályra a másoló konstruktor x ( &x).

Másoló konstruktor A String osztály kiterjesztése másoló konstruktorral: class String { .......... String ( String& s ); }; String::String ( String& s ) { pstring = new char [size = s.size ]; strcpy ( pstring, s.pstring); }  

Másoló konstruktor Definícióban történő inicializálás (az előbb láttuk a példát) Függvény argumentum és visszatérési érték Érték szerinti paraméterátadás esetén az argumentumok a verem memóriába kerülnek. A verem memórián tartózkodó ideiglenes változóba másolás megfelel az inicializálatlan objektum kitöltésének. A verembe másolást a másoló konstruktor végzi el.  

s0 vermen lévő másolatát s-et a másoló konstruktor inicializálja. Hívás Hívott String s0, s1; s1 = f (s0); String f ( String s ) { String r; //(stack) temp temp ..... return r; } // r, s

Visszatérési érték kezelése - skalár érték esetén regisztert használnak - objektumok azonban nagyobb méretűek, így gyakran a globális memóriát, a heap-et vagy a veremmemóriában lefoglalt területet kell igénybe venni. A visszatérési értéket átadó memóriaterület azonban inicializálatlan, tehát a return utasítás is csak a másoló konstruktor hívásával másolhatja be a visszatérési értéket.  

Tanulságok A létrehozott String osztály tulajdonságai: - dinamikusan nyújtózkodó szerkezet, amely minden pillanatban csak annyit foglal el a memóriából, amennyit feltétlenül szükséges. - String típusú objektumok tetszőleges számban előállíthatók. Olyan egyszerűen használhatók, mint a beépített típusok.

Öröklés Az örököltetés szintaktikája: class származtatott osztály_név: elérési mód bázis-osztály_név { // … }

Elérési módok a származtatásnál public private protected

A származtatás: public //Alaposztály class base { int x; public: void setx (int n ) { x=n; } void showx() { cout <<x << ‘\n’; } };

Származtatott osztály class derived : public base { int y; public: void sety (int n ) { y=n; } void showy() { cout <<y << ‘\n’; } };

Publikus tagok elérése main() { derived ob; ob.setx (10); //eléri az alaposztály tagjait ob.sety (20); //eléri a származtatott osztály tagjait ob.showx (); //eléri az alaposztály tagjait ob.showy (); //eléri a származtatott osztály tagjait return 0; }

A private tagok nem elérhetők //Alaposztály class base { int x; public: void setx (int n ) { x=n; } void showx() { cout <<x << ‘\n’; } };

private tagra nem hivatkozhatunk! class derived : public base { int y; public: void sety (int n ) { y=n; } void show_sum() { cout <<x+y << ‘\n’; } //hiba! //x private tag void showy() { cout <<y << ‘\n’; } };

A származtatás: private //Alaposztály class base { int x; public: void setx (int n ) { x=n; } void showx() { cout <<x << ‘\n’; } };

Származtatott osztály class derived : private base { int y; public: void sety (int n ) { y=n; } void showy() { cout <<y << ‘\n’; } };

Publikus tagok elérése main() { derived ob; ob.setx (10); //hiba, ez privát a származtatott osztályban ob.sety (20); //eléri a származtatott osztály tagjait ob.showx (); //hiba, ez privát a származtatott osztályban ob.showy (); //eléri a származtatott osztály tagjait return 0; }

Megoldás az előző példára A származtatás: private //Alaposztály class base { int x; public: void setx (int n ) { x=n; } void showx() { cout <<x << ‘\n’; } };

Származtatott osztály class derived : private base { int y; public: void setxy (int n, int m ) {setx(n); y=m; } void showxy() {showx(); cout <<y << ‘\n’; } };

Publikus tagok elérése main() { derived ob; ob.setxy(10,20); //eléri a származtatott osztály tagjait ob.showxy (); //eléri a származtatott osztály tagjait return 0; }

protected tagok elérése //Alaposztály class samp { int a; protected: int b; public: int c; samp(int n, int m) { a=n; b=m;} int geta ( ) { return a; } int getb ( ) {return b;} };

Hozzáférés protected tagokhoz main() { //ob.b=99; //hiba!!! ob.c=30; //OK. cout<< ob.geta() << ‘ ‘; cout<< ob.getb() << ‘ ‘<<ob.c<<‘\n’; return 0; }

protected tagok //Alaposztály class base { protected: int a,b; public: void setab(int n, int m) { a=n; b=m;} };

Származtatott osztály class derived : public base { public: void setc (int n) { c=n;} void showabc() { cout<<a<<‘ ‘ <<b<< ‘ ‘ <<c << ‘\n’; } };

Publikus tagok elérése main() { derived ob; ob.setab(1,2); ob.setc (); Ob.showabc(); return 0; }

Konstruktorok, destruktorok és a származtatás A bázis osztály és a származtatott osztályok is rendelkezhetnek konstruktorokkal és destruktorokkal. A konstuktorok végrahajtásának sorrendje a származtatásnak megfelelő sorrendben történik. A destruktorok végrehajtása a származtatás sorrendjével ellenkező sorrendben történik.

Konstruktorok paraméterei Különböző esetek: Alaposztálynak és származtatott osztálynak nincs paramétere Alaposztálynak nincs paramétere Származtatott osztálynak nincs, de a bázis osztálynak van paramétere Bázis osztálynak is és a származtatott osztálynak is van paramétere.

Bázis és származtatott osztály konstruktorainak végrehajtási sorrendje #include <stdio.h> class base { public: base { cout << „Bázis osztály konstruktora\n”;} ~base { cout << „Bázis osztály destruktora\n”;} }; Class derived: public base { public; derived { cout << „Származtatott osztály konstruktora\n”;n ~derived { cout << „Származtatott osztály destruktora\n”;}

A konstruktorok és destruktorok lefutása main () { derived o; return 0; } Output: Bázis osztály konstruktora Származtatott osztály konstruktora Származtatott osztály destruktora Bázis osztály destruktora

Paraméterek átadása #include <stdio.h> class base { int i; public: base ( int n) { cout << „Bázis osztály konstruktora\n”; i=n;} ~base { cout << „Bázis osztály destruktora\n”;} void show() { cout <<i << ‘\n’; } };

class derived: public base { int j; public; derived ( int n, int m) : base(m) { cout << „Származtatott osztály konstruktora\n”; j=n; } ~derived { cout << „Származtatott osztály destruktora\n”;} void showj () { cout<< j << ‘\n’;} };

main() { derived o(10,20); o.showi(); o.showj(); return 0; }