Programozás módszertan

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

Globális operátor overloading

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

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

Objektumok inicializálása

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

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

Bevezetés, a C++ osztályok. Pere László

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?

JAVA PROGRAMOZÁS 2.ELŐADÁS

Osztályok. 4. gyakorlat

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

Osztály és objektum fogalma

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)

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

Java II. I A Java programozási nyelv alapelemei

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

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

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

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

C++ programozási nyelv

Objektumelvű programozás

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Java és web programozás

C# osztálydeníció. Krizsán Zoltán 1. .net C# technológiák tananyag objektum orientált programozás tananyag

A C++ szigorúbban kezeli a típuseltéréseket, mint a C nyelv Lehetséges típuskonverziók:

1. Bevezetés A C++ nem objektumorientált újdonságai 3

és az instanceof operátor

3. Osztályok II. Programozás II

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

- 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]++;

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

Programozás módszertan p.1/46

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

1. Alapok. Programozás II

Programozás C++ -ban 2007/7

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

Elemi Alkalmazások Fejlesztése II.

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

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

C++ programozási nyelv Konstruktorok-destruktorok

Kifejezések. A programozás alapjai előadás. Operátorok. Kifejezések. Operátorok precedenciája. Operátorok precedenciája

Java II. I A Java programozási nyelv alapelemei

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

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

Kifejezések. Kozsik Tamás. December 11, 2016

Java V. Osztályszint. lyszintű ű tagok. Példányváltozó. Osztályváltozó. Általános Informatikai Tanszék Utolsó módosítás:

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

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Java programozási nyelv 4. rész Osztályok II.

Programozás C++ -ban

OOP: Java 8.Gy: Abstract osztályok, interfészek

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Programozás C és C++ -ban

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

A függvények névvel rendelkező utasításcsoportok, melyeknek információkat adhatunk át, és van egy visszatérési értékük.

Objektum orientált kiterjesztés A+ programozási nyelvhez

1. Öröklés Rétegelés Nyilvános öröklés - isa reláció Korlátozó öröklődés - has-a reláció

Programozási nyelvek Java

Java programozási nyelv 5. rész Osztályok III.

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) {} };

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

Bevezetés a C++ programozási nyelvbe

A C programozási nyelv III. Pointerek és tömbök.

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

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

Web-technológia PHP-vel

Kivételkezelés a C++ nyelvben Bevezetés

A C programozási nyelv III. Pointerek és tömbök.

Pénzügyi algoritmusok

Java és web programozás

Java és web programozás

1000.AA Megoldo Alfréd 1000.A

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

Memóriakezelés, dinamikus memóriakezelés

Programozási nyelvek (ADA)

Öröklés és Polimorfizmus

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

Már megismert fogalmak áttekintése

Származtatási mechanizmus a C++ nyelvben

Google C++ style guide

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

Kifejezések. Kozsik Tamás. December 11, 2016

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

Interfészek. PPT 2007/2008 tavasz.

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

Smalltalk 3. Osztályok létrehozása. Készítette: Szabó Éva

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)

.AA Megoldó Alfréd AA.

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

Programozási nyelvek Java

1) Hány byte-on tárol a C++ egy karaktert (char)? implementáció-függő ( viszont lásd 79. megjegyzés ) 1 8 4

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

Osztályok. construct () destruct() $b=new Book(); $b=null; unset ($b); book.php: <?php class Book { private $isbn; public $title;

Mutatók és mutató-aritmetika C-ben március 19.

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

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

Készítette: Nagy Tibor István

Átírás:

Programozás módszertan p. Programozás módszertan Operátorok túlterhelése a C++ nyelvben Pere László (pipas@linux.pte.hu) PÉCSI TUDOMÁNYEGYETEM TERMÉSZETTUDOMÁNYI KAR INFORMATIKA TANSZÉK

Bevezetés Programozás módszertan p.

Programozás módszertan p. Operátorok túlterhelése A programozás során gyakran használunk operátorokat a programban elvégzendő feladatok tömör, olvasható kifejezésére. Az operátorok a beépített típusok kezelésére kitűnően használhatók, a programozó által létrehozott típusok, osztályok kezelésére azonban természetesen nem alkalmasak változatlan formájukban. Megoldást az operátorok túlterhelése (operator overloading) jelentheti. A túlterhelés segítségével a programozó meghatározhatja, hogy mi történjék az általa létrehozott típusokkal az egyes operátorok hatására.

Programozás módszertan p. Operátorok túlterhelése Az operátorok túlterhelése során megváltoztathatjuk az egyes operátorok jelentését, de: az operátor túlterhelés segítségével nem hozhatunk létre új operátorokat, nem változtathatjuk meg az operátorok aritását, nem változtathatjuk meg az operátorok precedenciáját. Nyilvánvaló, hogy ezek a megkötések korlátot szabnak a programozó dühöngő alkotói vágyának és megakadályozzák a nyelv felismerhetetlenségig fajuló torzítását.

Programozás módszertan p. Túlterhelhető operátorok A következő operátorok túlterhelhetők: + - * / % ^ & ~! = < > += -= *= /= %= ^= &= = << >> >>= <<= ==!= <= >= && ++ -- ->*, -> [] () new new[] delete delete[] A = (értékadó), & (címképző) és a, (kiválasztó) operátorok túlterhelés nélkül is érvényesek.

Programozás módszertan p. Nem túlterhelhető operátorok A következő operátorok nem túlterhelhetők: ::..*? : sizeof typeid Ezeknek az operátoroknak a túlterhelés nemkívánatos mellékhatásokkal járna, ezért nem lehet őket túlterhelni.

Programozás módszertan p. Előre meghatározott jelentés Bizonyos operátorok szokásos jelentései között összefüggés van. A a++ például általában megegyezik az a+=1 jelentésével, ami ugyanaz, mint a=a+1. Az ilyen hasonlóságokat a fordító túlterhelt operátorok esetében nem követi, azaz, ha ilyen tulajdonságokat kívánunk használni, magunknak kell megvalósítani őket.

A túlterhelés menete Programozás módszertan p.

Programozás módszertan p. A függvény neve A túlterhelés során az operátort megvalósító utasításokat függvényként adjuk meg. A függvény nevében az operator kulcsszót az operátor követi. Az operátor argumentumai a függvény argumentumai és visszatérési értéke, amelyek beépített típusok, objektumok (kis méret) vagy referenciák (nagy méret) lehetnek. Int &operator=(const int i);

Programozás módszertan p. 1 Unáris operátorok Az unáris operátorok megvalósíthatók: Paraméter nélküli nem statikus tagfüggvényként: Int &Int::operator++(void) {... return *this; } Egyparaméter nem tag függvényként: Int &operator++(int &i) {... return i; }

Programozás módszertan p. 1 Unáris operátorok A ++ és -- alapértelmezett esetben prefix, postfix változatot egy ál-argumentummal készíthetünk, amelynek típusa int. public: Int(void); Int(const Int &i); Int &operator=(const int i); Int &operator++(void); // Prefix Int &operator++(int); // Postfix

Programozás módszertan p. 1 Bináris operátorok A bináris operátorok megvalósíthatók: Egyparaméterű nem statikus tagfüggvényként: Int &Int::operator+=(Int a){ ival += a.ival; return *this; } Kétparaméterű nem tag függvényként: Int operator+(int &a, Int &b) { Int s = a; return s += b; }

Programozás módszertan p. 1 Tag vs. nem tag Az olyan operátorok, amelyek első paraméterként alaptípust fogadnak, nem lehetnek tagfüggvények, hiszen a taggfüggvények első, rejtett argumentumként csak objektum adható meg. Az a + 2 értelmezhető a.operator+(2) formában, mert az első paraméter nem alaptípus, így lehet a osztályának tagfüggvénye. A 2 + a viszont nem értelmezhető 2.operator+(a), formában, mert a 2 típusa int, ami nem osztály, így nem lehetnek tagfüggvényei.

Programozás módszertan p. 1 Tag vs. nem tag Előnyös, ha minél kevesebb függvény fér hozzá az objektum rejtett (private) adattagjaihoz, azaz, ha minél kevesebb tagfüggvényt készítünk a operátorok túlterhelése közben. Ezt úgy érhetjük el, ha csak azokat az operátorokat valósítjuk meg tagfüggvényként, amelyek módosítják első paraméterüket (például ++, =, +=). Azokat az operátorokat, amelyek csak új értéket állítanak elő, tagfüggvényekre visszavezetve nem tag függvényként valósíthatjuk meg.

Programozás módszertan p. 1 Tag vs. nem tag A következő részlet ezen meggondolás alapján készült: Int &Int::operator+=(Int a){ } ival += a.ival; return *this; Int &operator+(int &a, Int &b) { Int s = a; return s += b; }

Típuskonverzió Programozás módszertan p. 1

Programozás módszertan p. 1 A kezdeti értékadás Fel kell hívnunk a figyelmet, hogy a kezdeti értékadás nem egyezik meg az értékadással. A különbség különösen akkor szembeszökő, ha az operátorokat túlterheljük, mert a kezdeti értékadásnál nem használjuk a túlterhelt értékadó operátort. Az Int x = 10; tehát nem azonos az Int x; x = 10; kifejezésekkel.

Programozás módszertan p. 1 Egyparaméterű konstruktor Az egyparaméterű konstruktor konverziót jelent a paraméter típusáról a konstruktor típusára. Ezt kezdeti értékadás során is, és kifejezéseken belül is automatikusan használhatjuk, azaz a konstruktor nevét ilyen esetben nem kell kiírni. Hasonlóképpen használhatók a többparaméterű konstruktorok is, de azok nevét mindig ki kell írni.

Programozás módszertan p. 1 Egyparaméterű konstruktor inline Int::Int(int i) { initialized = true; ival = i; }... Int x = 10; Int z; z = x + 1;...

Programozás módszertan p. 2 Explicit konstruktorok Ha az egyparaméterű konstruktorra szükségünk van, de nem akarjuk automatikus típuskonverzióra használni, az explicit kulcsszót használhatjuk: class Int { public:... Int(void); explicit Int(int i); Az ilyen konstruktorok csak úgy használhatók típuskonverzióra, hogy kimondottan előírjuk a hívásukat: a = b + Int(1);

Programozás módszertan p. 2 Többparaméterű konstruktor A többparaméterű konstruktor nevét mindig ki kell írni: complex x = complex(2, 2); y = x + complex(4, 3); Viszont a kezdeti értékadást ilyen esetben a másoló konstrukor hívása nélkül is el lehet végezni: complex x(2, 2);

Programozás módszertan p. 2 Vegyes módú aritmetika Ha az egyparaméterű konstruktor hívását el akarjuk kerülni mert például a konstruktor hívása nem olcsó, akkor használhatjuk a vegyes módú aritmetika módszerét is. A módszer lényege, hogy a túlterhelt operátorváltozatokból a fordító az argumentumok alapján azt választja ki, amelyikre szükség van, nem az argumentumot konvertálja a függvényparaméterre. E módszer hátránya, hogy fárasztó a sokféle függvény elkészítése, közben hibákat véthetünk.

Programozás módszertan p. 2 Vegyes módú aritmetika complex operator+(complex a, complex b) { complex r = a; return r += b; // b complex } complex operator+(complex a, double b) { complex r = a; return r += b; // b double } complex operator+(double a, complex b) { complex r = b; return r += a; // a double }

Programozás módszertan p. 2 Konverziós operátorok A konstruktorral elvégzett típuskonverzió nem alkalmas beépített alaptípusra való konverzióra, mert az alaptípusoknak nincsen konstruktora, régebben létrehozott osztályokra való konverzióra, ha a régebbi osztály nem módosítható. Ilyen esetekben konverziós operátorokat használhatunk.

Programozás módszertan p. 2 Konverziós operátorok Ha T és X egy-egy típus neve, akkor a X::operator T() függvény határozza meg az X típusról a T típusra való konverziót. A konverziós operátor visszatérési értékének típusát nem adhatjuk meg, ilyen értelemben a konverziós operátor hasonlít a konstruktorokra. A konverziós operátorok hívása automatikusan történik. Ha túl sok konverziós operátort készítünk, a kifejezések többértelművé válhatnak!

Programozás módszertan p. 2 Konverziós operátor A következő függvény az Int típusról konvertál int típusra: Int::operator int const() { } return ival;

A friend Programozás módszertan p. 2

Programozás módszertan p. 2 A friend Amikor egy tagfüggvényt hozunk létre, három dolgot jelzünk: 1. A függvény hozzáférhet a privát tagokhoz. 2. A függvény az osztály hatókörébe tartozik. 3. A függvényt az osztály egy objektumára kell meghívni. A static esetében csak az első kettő, a friend esetében pedig csak az első érvényes.

Programozás módszertan p. 2 Szükségszerűség A friend módosító használata szükséges, ha olyan operátort valósítunk meg, amelynek operandusai és/vagy eredménye különbözők, ezért szükséges, hogy több osztály privát tagjaihoz is hozzáférjen a megvalósító függvény. Az ilyen esetekben nem tudjuk elkerülni a friend módosító használatát.

Programozás módszertan p. 3 A friend függvény (nem tag) class Matrix; class Vector {... friend Vector operator*(const Matrix&, const Vector&); }; class Matrix {... friend Vector operator*(const Matrix&, const Vector&); };

Programozás módszertan p. 3 A friend függvény (nem tag) Vector operator*(const Matrix&, const Vector&) {... }

Programozás módszertan p. 3 A friend függvény (tag) A friend függvény lehet egy másik osztály tagfüggvénye: class List_iterator { };... int *next(); class List {... friend int *List_iterator::next(); };

Programozás módszertan p. 3 A friend osztály Ha egy osztály minden tagfüggvénye friend, egyszerűsített jelölést is használhatunk: class List { };... friend class List_iterator;

Nagyméretű objektumok Programozás módszertan p. 3

Programozás módszertan p. 3 Argumentumok Az operátotok túlterhelésére használt függvények argumentumai lehetnek objektumok, de ez nagyméretű objektumok esetében nem szerencsés. Mutatókat nem használhatunk argumentumként, mert a mutatókra alkalmazott operátorok nem terhelhetők túl. A referenciák argumentumként használva lehetővé teszik a nagyméretű objektumok kezelését anélkül, hogy lemásolnánk őket.

Programozás módszertan p. 3 Visszatérési érték Az operandusok értékét megváltoztató operátorok (például ++, --) a megkapott referenciát módosítás után referenciaként visszaadhatják. Azon operátorok, amelyek új értéket hoznak létre (például +, -), referenciát visszaadva lokális változójuk referenciáját adnák vissza, ami tiltott művelet. Mivel az operátot egy kifejezésen belül többször is szerepelhet, a visszaadott érték nem lehet lokális statikus változó referenciája sem. A legegyszerűbb megoldás a visszatérési érték másolása.

Indexelés Programozás módszertan p. 3

Programozás módszertan p. 3 Indexelés Az indexelést a [] operátor túlterhelésével befolyásolhatjuk. Az operator[] függvénynek tagfüggvénynek kell lennie, paramétere azonban tetszőleges típusú lehet, így készíthetünk akár asszociatív tömböt is. Az operator[] rejtett operátora természetesen maga az objektum, amelyet tömbként idexelni akarunk.

Programozás módszertan p. 3 Indexelés Figyeljük meg, hogy az indexelés során az előzőekben elmondottakkal ellentétben referenciát, balértéket kapunk: class Assoc { public: Assoc(); const double &operator[](const string &); double &operator[](string &); }...

Függvényhívás Programozás módszertan p. 4

Programozás módszertan p. 4 A függvényhívás A függvényhívó operátor túlterhelése olyan osztályok esetében hasznos, amelyeknek csak egy műveletük van. Ez triviális, hiszen ha a egy objektum, akkor a a() a függvényhívás, ami csak egyféle lehet. A függvényhívó operátor túlterhelése az operator() nevű függvény megvalósításával történhet.

Az indirekció Programozás módszertan p. 4

Programozás módszertan p. 4 Az indirekció A -> az indirekció operátora egyparaméterű posztfix operátorként terhelhető túl. Az argumentum a -> bal oldala, visszatérési értékének mutatónak kell lennie, amire az indirekció vonatkozni fog. A -> túlterhelésével smart pointer készíthető, amellyel a hivatkozás esetén mindig csinálni akarunk valamit.

Programozás módszertan p. 4 Példa A következő példa bemutatja, hogyan készíthetünk pointert, ami a hivatkozáskor beolvassa az adatokat a háttértárról: Rec *Rec_ptr::operator->() { if (in_core_address == 0) in_core_address = read_disk(id); } return in_core_address;

Programozás módszertan p. 4 Kötelező irodalom [1] BJARNE STROUSTRUP: A C++ Programozási Nyelv, Kiskapu Kiadó Budapest, ISBN: 963 9301 18 3, 343 393. o.