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

Hasonló dokumentumok
3. Osztályok II. Programozás II

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

Objektumok inicializálása

Programozás módszertan

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

A feladat lényege egy felhasználói típusnak a zsák típusnak a megvalósítása.

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

.AA Megoldó Alfréd AA.

500. AA Megoldó Alfréd AA 500.

Programozás II. 6.Öröklés Dr. Iványi Péter

Alkalmazott modul: Programozás 9. előadás. Strukturált programozás: dinamikus adatszerkezetek

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

500. CC Megoldó Alfréd CC 500.

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

117. AA Megoldó Alfréd AA 117.

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

Globális operátor overloading

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

Programozás C++ -ban

Bevezetés a programozásba I.

Programozás C++ -ban 2007/7

Osztály és objektum fogalma

C++ programozási nyelv Konstruktorok-destruktorok

- 1 - Konstansok használata. Döntsük el, van-e fordítási idejű hiba az alábbi programrészletekben! a) const char * str="zh"; str[0]++;

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.

1. Alapok. Programozás II

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

500. DD Megoldó Alfréd DD 500.

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

AA MEGOLDÓ ALADÁR AA

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

128. AA Megoldó Alfréd AA 128.

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

Származtatási mechanizmus a C++ nyelvben

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

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

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

503.AA Megoldo Arisztid 503.A

feladat pont min elért

Osztályok. 4. gyakorlat

Mit ír ki? feladatok megoldásokkal

Dinamikus csatolású függvénykönyvtár készítése és használata Plugin-szerű betöltés Egyszeű C++ osztályok készítése

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

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

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

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

C++ Gyakorlat jegyzet 7. óra

C++ programozási nyelv

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

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

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

Programozás C++ -ban

XIII. STL. Tároló Bejáró Algoritmus. XIII.1 A vector #include <vector> #include <vector> #include <algorithm> using namespace std;

Pénzügyi algoritmusok

Bevezetés a programozásba. 9. Előadás: Rekordok

A C++11 újdonságai. Smidla József Operációkutatási Laboratórium október 9.

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)

Generikus Típusok, Kollekciók

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

Bevezetés a programozásba. 11. Előadás: Esettanulmány

Maximum kiválasztás tömbben

Bevezetés a programozásba 2

1000.AA Megoldo Alfréd 1000.A

Programozási Nyelvek (C++) Összefoglaló

0. Megoldó Manó 0. Programozás alapjai 2. (inf.) pót zárthelyi gyak. hiányzás: 2 n/kzhp: n/11,5. ABCDEF IB.028/2.

Osztálytervezés és C++ implementációs ajánlások I.

Programfejlesztés. Programozás alapjai II. (3. ea) C++ Néhány programozási módszer. Korai szoftverkészítés jellemzői. Gépi nyelv? Strukturált tervezés

Programfejlesztés. Programozás alapjai II. (3. ea) C++ Néhány programozási módszer. Korai szoftverkészítés jellemzői. Gépi nyelv? Strukturált tervezés

Bevezetés a programozásba. 8. Előadás: Függvények 2.

Programozás C++ -ban 2007/4

Alkalmazott modul: Programozás 6. előadás. Strukturált programozás: újrafelhasználható adattípusok

228. AA Default Konstruktor AA 228.

Objektumelvű programozás

Programozás C++ -ban

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

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

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

OOP #14 (referencia-elv)

Bevezetés a programozásba I 8. gyakorlat. C++: szövegfolyamok, intelligens tömbök

A C++ Standard Template Library rövid összefoglalás

111. AA Megoldó Alfréd AA 111.

Az alábbi példában a Foo f(5); konstruktor hívása után mennyi lesz f.b értéke? struct Foo { int a, b; Foo(int c):a(c*2),b(c*3) {} };

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

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

infix kifejezés a+b ab+ +ab postfix kifejezés prefix kifejezés a+b ab+ +ab a+b ab+ +ab Készítette: Szabóné Nacsa Rozália

5. Gyakorlat. struct diak {

Programozás II gyakorlat. 6. Polimorfizmus

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

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 2.ELŐADÁS. Objektumorientált programozás

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

Elemi Alkalmazások Fejlesztése II.

Szövegek C++ -ban, a string osztály

500.AJ Megoldó Magyar Magdolna 500.J

Feladat: Nagy számok típusa: Típusérték-halmaz: Típusműveletek: Értékadás operátor: Bitshift << operátor: Összeadás operátor:

Objektum elvű alkalmazások fejlesztése. Verem típus osztály-sablonja

Bevezetés a programozásba I 8. gyakorlat. C++: szövegfolyamok, intelligens tömbök. Adatfolyamok Hibalehetőségek

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

Programozás alapjai II. (3. ea) C++ Panaszok kezelése. Hol tartunk?

Pénzügyi algoritmusok

Átírás:

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

Kezdő feladat Írjunk egy Vector osztályt, amely n db double értéket tárol. A konstruktor kapja meg az elemek számát. Írj egy set(int idx, double v) függvényt, amely az idx. elem értékét v-re állítja, valamint egy get(int idx)-et, amely visszaadja az idx. elem értékét! Ne feledkezz meg az elemek felszabadításáról sem! 2

Megoldás: main.cpp #include <iostream> #include "vector.h" using namespace std; int main() { Vector a(5); int i; for (i = 0; i < 5; i++) { a.set(i, i * 4.0); for (i = 0; i < 5; i++) { cout << a.get(i) << " "; cout << endl; 3

Megoldás: vector.h class Vector { double * elemek; int mennyi; public: Vector(int mennyi); ~Vector(); void set(int idx, double v); double get(int idx) const; ; 4

Megoldás: vector.cpp #include "vector.h" Vector::Vector(int mennyi) { this->mennyi = mennyi; elemek = new double[mennyi]; Vector::~Vector() { delete [] elemek; elemek = 0; void Vector::set(int idx, double v) { elemek[idx] = v; double Vector::get(int idx) const { return elemek[idx]; 5

Probléma Szeretnénk elérni, hogy a Vector osztályra is használhassuk a +, -, *, /, =, +=, [] stb. operátorokat: Vector a(5), b(5); a[4] = 3; b[2] = a[1] * 3; a += b; 6

Megoldás 1.: Találjuk ki, hogy mit jelentsenek a különböző operátorok a Vector osztályra alkalmazva 2.: Magyarázzuk el a C++-nak, hogy hogy kell értelmeznie az operátorokat Operátor túlterhelés 7

Operátor túlterhelés Terheljük túl a += operátort úgy, hogy az alábbi kifejezés hatása Vector a(5), b(5); a += b; az legyen, hogy a vektor minden i. eleméhez hozzáadjuk b i. elemét! 8

Operátor túlterhelés class Vector { double * elemek; int mennyi; public: Vector(int mennyi); ~Vector(); void set(int idx, double v); double get(int idx) const; ; void operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; 9

Operátor túlterhelés void operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; Vector a(5), b(5); a += b; 10

Operátor túlterhelés void operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; Vector a(5), b(5); a += b; 11

Operátor túlterhelés int a1, a2, a3; a1 += a2 += a3; Ennek mintájára: Vector a(5), b(5), c(5); a += b += c; 12

Operátor túlterhelés int a1, a2, a3; a1 += a2 += a3; Működik? Vector a(5), b(5), c(5); a += b += c; 13

Operátor túlterhelés void operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; Vector a(5), b(5), c(5); a += b += c; 14

Operátor túlterhelés void operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; Vector a(5), b(5), c(5); Kiértékelődik az operator+= által a += b += c; 15

Operátor túlterhelés void operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; Vector a(5), b(5), c(5); Az operator+= visszatérési értéke helyettesítődik be (ha lenne ) a += void 16

Operátor túlterhelés Vector & operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; return *this; Vector a(5), b(5), c(5); Kiértékelődik az operator+= által a += b += c 17

Operátor túlterhelés Vector & operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; return *this; Vector a(5), b(5), c(5); Behelyettesítődik b referenciájával! a += b 18

Operátor túlterhelés Vector & operator+=(const Vector & v) { int i; for (i = 0; i < mennyi; i++) elemek[i] += v.elemek[i]; return *this; Vector a(5), b(5), c(5); Újra meghívódik az operator+= függvény! a += b 19

= operátor Vector a(5), b(5); Vector c = a; // másoló konstruktor Ehhez viszont a = operátort kell túlterhelnünk: b = a; 20

= operátor Mi hiányzik? class Vector { double * elemek; int mennyi; public: [ ] Vector & operator = (const Vector & v) { mennyi = v.mennyi; elemek = new double[mennyi]; int i; for (i = 0; i < mennyi; i++) elemek[i] = v.elemek[i]; return *this; ; 21

class Vector { double * elemek; int mennyi; public: [ ] ; = operátor Fel kell szabadítani a már meglévő tömböt! (Ez nem konstruktor, itt már létezik az objektum!) Vector & operator = (const Vector & v) { delete [] elemek; mennyi = v.mennyi; elemek = new double[mennyi]; int i; for (i = 0; i < mennyi; i++) elemek[i] = v.elemek[i]; return *this; 22

= operátor Mi történik ekkor? Vector a; a = a; class Vector { double * elemek; int mennyi; public: [ ] Vector & operator = (const Vector & v) { delete [] elemek; mennyi = v.mennyi; elemek = new double[mennyi]; int i; for (i = 0; i < mennyi; i++) elemek[i] = v.elemek[i]; return *this; ; 23

= operátor Az értékadó operátort létező objektumra hívjuk meg, esetünkben a Vector típusú objektumnak már létezik egy belső dinamikus tömbje. Hogy elkerüljük a memóriaszivárgást, ezt előbb fel kell szabadítani, hiszen a helyére újat hozunk létre. Az önmagának való értékadás hatására azonban felszabadul a tömb, amiből másolunk, ezt ne engedjük meg! 24

A helyes = operátor class Vector { double * elemek; int mennyi; public: [ ] ; Vector & operator = (const Vector & v) { if (&v == this) { return *this; delete [] elemek; mennyi = v.mennyi; elemek = new double[mennyi]; int i; for (i = 0; i < mennyi; i++) elemek[i] = v.elemek[i]; return *this; Önmagának való értékadás esetén kilépünk. Töröljük a régi tartalmat. Végül másolunk. 25

Destruktor, másoló konstruktor, = operátor A destruktor feladata: Felszabadítás Másoló konstruktor feladata: másolás = operátor feladata: Felszabadítjuk a meglévő adatokat, majd másolunk Az ismétlődő feladatok: felszabadítás és másolás Ötlet: Írjunk egy private clear függvényt a felszabadításra, és egy private copy függvényt a másolásra 26

Destruktor, másoló konstruktor, = operátor class Vector { double * elemek; int mennyi; void clear() { delete [] elemek; void copy(const Vector & v) { mennyi = v.mennyi; elemek = new double[mennyi]; int i; for (i = 0; i < mennyi; i++) elemek[i] = v.elemek[i]; 27

Destruktor, másoló konstruktor, = operátor public: [ ] Vector(const Vector & v) { copy(v); ~Vector() { clear(); Vector & operator = (const Vector & v) { if (&v == this) { return *this; clear(); copy(v); return *this; ; 28

Ha egy Ososztaly nevű osztályból származtattunk public: [ ] Vector(const Vector & v): Ososztály(v) { copy(v); ; ~Vector() { clear(); Vector & operator = (const Vector & v) { Ne felejtsük el meghívni a if (&v == this) { return *this; clear(); Ososztaly::operator=(v); copy(v); return *this; szülő másoló konstruktorát és a szülő = operátorát! 29

Operátor túlterhelés Írjunk operátort, amely segítségével jobbról megszorozhatjuk a vektort, a kifejezés egy új vektort ad eredményül! Vector a(5), b(5); a = b * 4; 30

Operátor túlterhelés class Vector { double * elemek; int mennyi; public: [ ] Vector operator * (double lambda) { Vector res = *this; int i = mennyi; while (i--) res.elemek[i] = elemek[i]*lambda; return res; ; 31

Operátor túlterhelés A már meglevő operátorok alapján működik-e a következő kód: Vector a(5), b(5); a = 4 * b; 32

Operátor túlterhelés A már meglevő operátorok alapján működik-e a következő kód: Vector a(5), b(5); a = 4 * b; Nem, mert a jelenlegi * operátor csak a jobbról való szorzásra működik! 33

Operátor túlterhelés Probléma: Olyan * operátor kell, amely bal oldala double, míg jobb oldala Vector & Két paraméteres operátor függvényre van szükségünk Ez már nem lehet tagja az osztálynak! 34

Operátor túlterhelés Az új operátort az osztályon kívül kell definiálni! Vector operator * (double lambda, const Vector & v) { Vector res = v; int i = v.mennyi; while (i--) res.elemek[i] = v.elemek[i]*lambda; return res; Mi ezzel a probléma? 35

Operátor túlterhelés A függvény nem éri el a private adattagokat! Engedjük meg kivételesen neki, hogy hozzáférhessen! Class Vector { double * elemek; int mennyi; public: [ ] friend Vector operator * ( double lambda, const Vector & v); ; 36

Operátor túlterhelés Prefix operátor: Vector & operator++ () { int i = mennyi; while (i--) elemek[i]++; return *this; Vector a(5); ++a; 37

Operátor túlterhelés Prefix operátor: Vector & operator++ () { int i = mennyi; while (i--) elemek[i]++; return *this; Vector a(5); ++a; Postfix operátor: Vector & operator++ (int) { int i = mennyi; Vector b(5); while (i--) b++; elemek[i]++; return *this; 38

Érdekesebb operátorok Használjuk tömbként az osztályunkat! class Vector { double * elemek; int mennyi; public: [ ] ; double & operator[](int index) { Vector a(5); a[0] = 32; a[3] = 10; return elemek[index]; 39

Érdekesebb operátorok Írjuk felül a << operátort úgy, hogy ki tudjuk íratni a vektorunkat! class Vector { double * elemek; int mennyi; public: [ ] friend ostream & operator<<(ostream & os, const Vector & v) { for (int i = 0; i < v.mennyi; i++) os<<v.elemek[i]<<" "; return os; ; Vector a(5), b(5); cout << a << endl << b << endl; 40

A túlterhelhető operátorok + - * / % ^ & -> ~! = < > += [] -= *= %= ^= &= = () << >> && =!= <= >= >>= <<= ++ - ->*, new new[] delete delete[] 41

Operátor túlterhelés Új operátort nem hozhatunk létre Az új operátoroknak tartalmazniuk kell újonnan definiált típusokat (vagy azok tagfüggvényeinek kell lenniük) Precedencia nem változtatható Asszociativitás nem változtatható 42

Feladat Add hozzá a következő operátorokat a Vector osztályhoz: -, / : Páronként kivonják / elosztják az elemeket, az eredmény egy új vektor. * : Ha két vektort szorzunk össze, akkor a Skaláris szorzatot kapjuk 43

Feladat Add hozzá a következő operátorokat a Vector osztályhoz: << Ha a jobb oldal egész szám, a bal oldal Vector, akkor a jobb oldalon látható értékkel tolja el az elemeket annyival kisebb indexű helyre. >> Ugyanaz, mint az előző, csak másik irányba végezzük az eltolást. 44