Tartalom C áttekintés C++ áttekintés Objektumok közötti kommunikáció. Budapesti Műszaki és Gazdaságtudományi Egyetem. C / C++ áttekintés

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

Pénzügyi algoritmusok

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

Már megismert fogalmak áttekintése

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

OOP #14 (referencia-elv)

C++ programozási nyelv

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

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

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

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. 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?

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

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

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

és az instanceof operátor

Mintavételes szabályozás mikrovezérlő segítségével

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

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

3. Osztályok II. Programozás II

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

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

Bánsághi Anna 2014 Bánsághi Anna 1 of 33

Java II. I A Java programozási nyelv alapelemei

5. Gyakorlat. struct diak {

Programozás I gyakorlat

Programozási alapismeretek 4.

C++ programozási nyelv

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

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

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

Programozás II gyakorlat. 6. Polimorfizmus

C++ programozási nyelv Konstruktorok-destruktorok

Bevezetés a Python programozási nyelvbe

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

Interfészek. PPT 2007/2008 tavasz.

OOP. Alapelvek Elek Tibor

Osztálytervezés és implementációs ajánlások

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ó

Osztálytervezés és implementációs ajánlások

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

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

Osztályok. 4. gyakorlat

Programozás C és C++ -ban

Programozási nyelvek JAVA EA+GY 1. gyakolat

Alprogramok, paraméterátadás

Bevezetés a programozásba előadás: Öröklődés

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

1. Alapok. Programozás II

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

Pénzügyi algoritmusok

500. AA Megoldó Alfréd AA 500.

Bánsághi Anna 2014 Bánsághi Anna 1 of 31

Objektumok inicializálása

Osztály és objektum fogalma

Java II. I A Java programozási nyelv alapelemei

JAVA PROGRAMOZÁS 2.ELŐADÁS

117. AA Megoldó Alfréd AA 117.

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

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

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Gregorics Tibor Tanácsok modularizált programok készítéséhez 1

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Szoftvertechnológia alapjai Java előadások

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

Programozás C++ -ban

Bevezetés a C++ programozási nyelvbe

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

Programozási nyelvek Java

OOP #1 (Bevezetés) v :39:00. Eszterházy Károly Főiskola Információtechnológia tsz. Hernyák Zoltán adj.

Programozás C++ -ban 2007/4

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

Objektumorientált programozás C# nyelven

Óbudai Egyetem. C programozási nyelv

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

C programozási nyelv

Programozási nyelvek Java

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

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

Bevezetés a programozásba II. 8. Előadás: Osztályok, objektumok, osztályszintű metódusok

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

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

A C programozási nyelv II. Utasítások. A függvény.

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

Fejlett programozási nyelvek C++ Iterátorok

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

Java programozási nyelv

Pénzügyi algoritmusok

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

S0-02 Típusmodellek (Programozás elmélet)

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Előfeldolgozó rendszer Tömbök. Dr. Bécsi Tamás 4. Előadás

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

Felhasználó által definiált adattípus

Java bevezet o Kab odi L aszl o Kab odi L aszl o Java bevezet o

Globális operátor overloading

11. gyakorlat Sturktúrák használata. 1. Definiáljon dátum típust. Olvasson be két dátumot, és határozza meg melyik a régebbi.

C programozási nyelv

Programozás C++ -ban

Java III. I I. Osztálydefiníció (Bevezetés)

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

Átírás:

Budapesti Műszaki és Gazdaságtudományi Egyetem C / C++ áttekintés Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter Elektronikus Eszközök Tanszéke 2014. augusztus 18. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 1 / 53

Tartalom Tartalom A C nyelv áttekintése A C++ nyelv és alapfogalmak áttekintése Objektumok közötti kommunikáció megvalósítása C++-ban Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 2 / 53

C áttekintés Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 3 / 53

Procedurális programozás Procedurális programozás alapelvek A modellezés alapegységei (tervezési egység) összetartozó adatokból (adatszerkezet, struktúra) és az adatokon elvégezhető műveletekből állnak. A procedurális programnyelvek (pl. C) nyelvi szinten nem támogatják az adatszerkezetek és a rajtuk elvégezhető műveletek egységét. A C nyelv a következőképpen valósítja meg a procedurális programozás alapelemeit: Adatok Beépített adattípusok Felhasználói adattípusok (tömbök, struktúrák) Műveletek: függvények Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 4 / 53

Adatszerkezetek Beépített típusok Alaptípusok int: egész, min. 32 bit float: szimpla pontosságú lebegőpontos, min. 32 bit double: dupla pontosságú lebegőpontos, min. 64 bit char: a legkisebb megcímezhető memóriaterület, 8 bit _Bool: kétállapotú típus (C99) Típusminősítők: long, long long, short, unsigned, signed Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 5 / 53

Adatszerkezetek Felhasználói típusok Összetartozó adatok tárolására alkalmas komplex adatszerkezetek tömb (array): azonos típusú adatok tárolására struktúra (structure): eltérő típusú adatok tárolására typedef struct core { struct instruction const * pmem ; int * dmem ; struct instruction ir; unsigned ip; _Bool z; _Bool n; int rf [16]; char instruction_code [10]; unsigned destination_index ; unsigned op_a ; unsigned op_b ; int immediate ; int mar ; int mdr ; _Bool run ; core ; int data_memory [256]; structure core my_core ; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 6 / 53

Függvények Függvények I. Önálló programrész, amely valamilyen gyakori feladatot végez A program bármely részéről hívható, lefutása után a végrehajtás a függvényhívás utáni első utasításnál folytatódik Jól definiált interfész paraméterlista visszatérési érték Függvény deklarációja függvény neve visszatérési érték típusa paraméterek típusa Függvény definíciója függvény neve visszatérési érték típusa paraméterek neve és típusa funkció Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 7 / 53

Függvények Függvények II. Deklaráció: void core_init ( struct core * the_core, struct instruction const * a_pmem, int * a_dmem ); Definíció: void core_init ( struct core * the_core, struct instruction const * a_pmem, int * a_dmem ) { the_core ->pmem = a_pmem ; the_core ->dmem = a_dmem ; instr_init (&( the_core ->ir )); for ( unsigned i = 0; i < 16; ++i) the_core ->rf[i] = 0; strcpy ( the_core -> instruction_code," -");...... Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 8 / 53

Függvényargumentumok Érték szerinti paraméterátadás Érték szerinti paraméterátadás esetén a függvény hívásakor a paraméterről másolat készül a stack-en. A hívó nem látja a függvény által végrehajtott változtatásokat. Nagy méretű objektumok átadása lassú és memóriaigényes lehet. void add ( int const op_a, int const op_b, int result ) { result = op_a + op_b ; Probléma: A result változóról a híváskor másolat készült, ez a másolat kapja meg az összeg értékét. A függvény tehát így nem működik. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 9 / 53

Függvényargumentumok Cím szerinti paraméterátadás Cím szerinti paraméterátadás esetén a függvény hívásakor a paraméternek csak a címe adódik át. A cím szerint átadott változón végrehajtott műveleteket a hívó is látja. void add ( int const op_a, int const op_b, int * result ) { * result = op_a + op_b ; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 10 / 53

Függvényargumentumok Visszatérési érték Ha a függvény eredménye egyetlen objektum, akkor az visszaadható visszatérési értékként. A visszatérési értéket általában hibakód visszaadására használjuk. Vigyázat!: lokális változóra mutató pointer visszaadása! int pmem_read_asm ( char const *path,...) {...... if (( asm_file = fopen ( path, "r ")) == NULL ) { fprintf ( stderr, " ERROR : file not found!\ n "); return -1; else { while (! end_of_file ) {...... return 0; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 11 / 53

Modellezés procedurális programozási nyelvekkel Tervezési egyed tipikus felépítése A modellezendő objektumot leíró adatszerkezet A modellezendő objektummal kapcsolatos műveletek typedef struct instruction { unsigned address ; char label [30]; char mnemonic [10]; unsigned destination_index ; unsigned op_a_index ; unsigned op_b_index ; int imm ; char jmp_destination [30]; instruction ; void instr_init ( struct instruction * instr ); void instr_cpy ( struct instruction * dest, struct instruction const * src ); void instr_print ( struct instruction const * instr ); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 12 / 53

Modellezés procedurális programozási nyelvekkel Tervezési egyed inicializálása Minden struktúrához tartozik egy inicializáló rutin. Az inicializáló rutint legalább egyszer, a deklaráció után közvetlenül hívjuk! void instr_init ( struct instruction * instr ) { instr -> address = 0; strcpy ( instr -> label, " -"); strcpy ( instr -> mnemonic, " -"); instr -> destination_index = 0; instr -> op_a_index = 0; instr -> op_b_index = 0; instr ->imm = 0; strcpy ( instr -> jmp_destination, " -"); struct instruction recent_instruction ; instr_init (& recent_instruction ); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 13 / 53

C++ áttekintés Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 14 / 53

OOP alapfogalmak OOP alapfogalmak Osztály Egyformán viselkedő dolgok átfogóan. Másképpen: adatok és a rajtuk értelmezett műveletek egysége. Objektum Egy konkrét valami, amelyik egy osztályba tartozik. Összeadók osztálya Mindegyiknek van A, B, és Cin (átvitel) bemenete. Mindegyiknek van S és Cout kimenete. Mindegyik összeadást csinál. Összeadó objektumok Konkrét példányok az áramkörben. Más bemeneteik vannak, máshova kerül a kimenetük. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 15 / 53

OOP alapfogalmak Osztály kódja C++-ban Osztály: class Osztaly { public : int tagvaltozo ; void tagfuggveny ( int param ); ; Példányosítás: Osztaly obj ; int x = 2; obj. tagvaltozo = x; obj. tagfuggveny (3); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 16 / 53

OOP alapfogalmak Tagfüggvények Tagfüggvények definíciója: void Osztaly :: tagfuggveny ( int param ) { tagvaltozo = param ; this -> tagvaltozo = param ; A tagfüggvények mindig egy konkrét objektumon dolgoznak. OOP nyelvekben: this me self Az objektum szemszögéből írjuk a programot! Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 17 / 53

Öröklődés Öröklődés I. Az OO nyelvek lehetővé teszik, hogy osztályokat származtassunk. A leszármazott osztályok kiterjesztik az alaposztályt, esetleg részben megváltoztatják azt. Így csak az újdonságokat kell leprogramozni. Kevesebb munka! LSP Liskov Substitution Principle. Valami egyfajta valami a gólya egyfajta madár. Az összeadó egyfajta kombinációs hálózat. Polimorfizmus = többalakúság. A gólya madárként viselkedik. Az összeadó kimenetei a bemenetek pillanatnyi értékeitől függenek. A kombinációs hálózatok általában is ilyenek. Osztálykönyvtárakban: egy adott ősosztályból kell származtatnunk a sajátunkat, ezzel illesztjük bele abba a rendszerbe. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 18 / 53

Öröklődés Öröklődés II. Alaposztály: class Madar { public : Szarny bal, jobb ; void repul (); ; Leszármazott, rendelkezik az alaposztály tulajdonságaival: class Kakas : public Madar { public : void qqriq (); ; Kakas k; k. qqriq (); k. repul (); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 19 / 53

Operátorok Operátorok átdefiniálása I. A saját típusú objektumainkra megadhatjuk, mit jelentsenek a beépített operátorok, pl. +, -, *, / stb. class Tort { public : int sz, n; Tort ( int szaml, int nev ) { sz= szaml ; n= nev ; ; Tort operator *( Tort t1, Tort t2) { return Tort ( t1. sz* t2.sz, t1.n* t2.n); ; Tort t1 (1,2), t2 (3,5); Tort t3 = t1* t2; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 20 / 53

Operátorok Operátorok átdefiniálása II. Mit is csinál a << operátor? Kiírjuk a képernyőre?! std :: ostream & operator <<( std :: ostream & os, Tort t) { os << t. sz << / << t.n; return os; int x; x = 1 << 5; Tort t1 (1, 2); std :: cout << t3; C++ jó szokás: az átdefiniált operátor csinálja azt, amit megszoktunk. Do like the ints do. Ezt gyakran sajnos nem tartják be. A << a nyelvbe épített ellentmondás :) Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 21 / 53

Adattag pointerek Adattag pointerek I. Normál pointer Egy konkrét objektumra mutat a memóriában. Önmagában használható. Adattag pointer Valamilyen osztálybeli (összes!) objektumok valamelyik adattagjára mutat. Csak egy konkrét objektumon használható. class Vektor { public : int x, y; ; int Vektor ::* tagptr ; tagptr = & Vektor :: x; Az osztály hozzátartozik a pointer típusához. int Vektor::* jelentése: a Vektor osztályban valamelyik intre mutató pointer. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 22 / 53

Adattag pointerek Adattag pointerek II. class Vektor { public : int x, y; v1, v2; int Vektor ::* tagptr ; tagptr = & Vektor :: x; v1.* tagptr = 3; // v1.x=3 v2.* tagptr = 4; // v2.x=4 tagptr = & Vektor :: y; v1.* tagptr = 5; // v1.y=5 v2.* tagptr = 6; // v2.y=6 Az az adattag, amelyikre mutat. Az az objektum, amelyiken használjuk! Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 23 / 53

Tagfüggvények pointerei Tagfüggvény pointerek Mint az adattag pointerek, csak tagfüggvényre. A típushoz hozzátartozik minden: a paraméterek, a visszatérési érték típusa; és persze maga az osztály. class Vektor { public : int x; Vektor ( int x_) { x=x_; int szimpla () { return x; int dupla () { return 2* x; ; Vektor v1 (5), v2 (6); int ( Vektor ::* v_fvptr )(); v_fvptr = & Vektor :: szimpla ; std :: cout << (v1.* v_fvptr )() << \n ; // 5 v_fvptr = & Vektor :: dupla ; std :: cout << (v2.* v_fvptr )() << \n ; // 12 Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 24 / 53

Tagfüggvények pointerei Callback függvények Callback = visszahívás. Megadunk egy függvényt, amelyet később valaki meghív. Grafikus alrendszer: megadunk egy függvényt, amelyet majd az meghív, amikor a gombra kattintottak. Szimulátor: megadunk egy függvényt, amelyet meghív, amikor egy esemény bekövetkezik. Ez a függvény itt tagfüggvény is lehet, adott objektumon: void SajatObjektum :: fuggveny () {... SajatObjektum s; szimulator. hivd_majd_meg (s, & SajatObjektum :: fuggveny ); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 25 / 53

Sablonok Sablonok I. Minták megírunk egy osztályt vagy függvényt úgy nagyjából. Kihagyunk belőle dolgokat. A kihagyott dolgokat, pl. egy típus nevét később megadhatjuk. Ugyanabból a sablonból a fordító legyártja a különféle osztályokat. Kb. search & replace módon csinálja. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 26 / 53

Sablonok Sablonok II. Ismerős példa: template <typename TIP > class Tomb { TIP * dintomb ; int meret ; public : Tomb ( int m) { meret = m; dintomb = new TIP [ meret ]; ; Tomb <int > inttomb (10); Tomb <double > doubletomb (20); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 27 / 53

Sablonok Sablonok III. Sablonparaméter nem csak típus neve lehet, hanem egy egész szám, és amúgy más típusok is. template <int DIM > class Koordinata { public : double komponensek [ DIM ]; ; Koordinata <2 > a; Koordinata <3 > b; Erről általában lebeszélnek megoldható dinamikus tömbbel is. De most nem programot írunk, hanem hardvert tervezünk! Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 28 / 53

Sablonok Sablonok IV. A sablonokból létrehozott konkrét osztályok egymástól teljesen függetlenek, nem kompatibilisek! Hasonlóan viselkednek, de külön típusok. enum Logikai { Nulla, Egy, Lebeg ; template <int SZELES > class Busz { public : Logikai bitek [ SZELES ]; Busz <8> busz1 ; Busz <32> busz2 ; busz1 = busz2 ; Ez jó, mert megvéd minket a hibáktól. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 29 / 53

Makrók Makrók I. A C/C++ nyelvekben a fordítás két fő lépése: 1 Előfeldolgozás ilyenkor kezeli a fordító az ún. makrókat, 2 Fordítás ekkor áll elő a programot megvalósító gépi kód. Az előfeldolgozót (preprocesszor) az annak szóló direktívákkal vezéreljük. Tulajdonképpen ezek nem C nyelvű utasítások, más szintaktikai szabályok vonatkoznak rájuk. Példák makró létrehozására: # define PI 3.1415926535 # define MAX (A,B) ((A) >(B )?( A ):( B)) Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 30 / 53

Makrók Makrók II. class Alaposztaly { public : void hello () { std :: cout << " hello "; ; # define LESZARMAZOTT_LETREHOZ ( NEV ) \ class NEV : public Alaposztaly LESZARMAZOTT_LETREHOZ ( Lesz ) { public : int x; ; Paraméteres makrók: nem igazi függvények, csak az előfeldolgozó kezeli őket. Furcsán kinéző dolgokat lehet létrehozni. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 31 / 53

Objektumok közötti kommunikáció Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 32 / 53

Kommunikáció a procedurális programozás során Kommunikáció a procedurális programozás során Procedurális programozás imperatív vezérlési szerkezetek (feltételes elágazás, ciklusok) felhasználói adatszerkezetek (struktúrák) függvények Bár az adatok és az hozzájuk kapcsolódó algoritmusok elvben itt is egységet alkotnak, ez a kód szintjén nem jelenik meg. A program egy tervezési egysége (modul): 1 a tulajdonságokat, jellemzőket leíró struktúra 2 a struktúrán műveleteket végző függvények Kommunikáció a program egységei között: adatok cseréje, műveletek végeztetése procedurálisan megtörténhet, hogy egy adott modulhoz tartozó függvény közvetlenül olvassa/írja egy másik modul adatait, műveletet végez azokkal ez nehezen áttekinthető függőségi hálót alakít ki egy nagy rendszerben Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 33 / 53

Objektum-orientált rendszertervezés Objektum-orientált rendszertervezés Az OOP rendszerek alapeleme az osztály: adatok és műveletek együtt egy objektum állapotát (az őt leíró adatokat) más egység nem értheti el az állapot megváltozása csak kérésre történhet függvényhívások segítségével Ez a tervezési elv zárt, önmagukban mindig konzisztens tervezési egységeket és az egységek között jól definiált kommunikációs felületeket (publikus függvények halmaza) eredményez. Ez hasonló a digitális rendszerekben található kommunikációs portok és protokolok rendszeréhez, ezért az OOP jól alkalmazható nagy digitális rendszerek leírására és modellezésére. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 34 / 53

Tartalmazás Tartalmazás Egy osztály adattagként tartalmazhatja egy másik osztály egy példányát. Ekkor nem önálló egységek kapcsolatát modellezzük, hanem egy részegységgel való belső adatcserét. Nyelvi szinten ez azt jelenti, hogy a részegység típusa és a konkrét példány tervezési időben kötött, később csak megváltoztatni lehet, lecserélni nem. class Processor { private : Memory memory ; ; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 35 / 53

Tartalmazás Belső osztály A tartalmazás olyan formában is megvalósulhat, hogy az egyik osztály a másikon belül van definiálva. Ilyenkor a belső osztály eléri a külső privát adattagjait. class Processor { public : class Memory {... ; private : Memory memory ;... ; Ha a belső osztály publikus, az azt jelenti, hogy a külső osztályon kívülről is látható, példányosítható. Egy belső osztályra való hivatkozás a külső segítségével történik: Processor::Memory memory; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 36 / 53

Tartalmazás Hivatkozás referenciával Az elérendő objektumra egy referencia mutat. A két objektum élettartama nincs összekötve, de a annak, amire referenciával hivatkozunk, hamarabb létre kell jönnie. Így a többalakúság már kihasználható az objektum pontos típusa nem kötött. Az elérendő objektumra mutató referenciát a saját objektum létrehozásának pillanatában be kell állítani és utána megváltoztatni nem lehet. class Processor { private : Memory & memory ; public : Processor ( Memory & memory ) : memory ( memory ) {... ; class DualPortMemory : public Memory {...; DualPortMemory dualportmemory ; Processor processor ( dualportmemory ); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 37 / 53

Tartalmazás Hivatkozás mutatóval Az elérendő objektumra egy pointer mutat. Kihasználható a többalakúság és bármikor beállítható vagy lecserélhető a hivatkozott objektum. Az objektumok élettartama teljesen független egymástól. class Processor { private : Memory * memory ;... ; Processor processor ; processor. setmemory (& dualportmemory );... processor. setmemory (& singleportmemory ); Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 38 / 53

Tartalmazás Kétirányú kommunikáció I. Tartalmazás esetén a tartalmazott objektum nem tudja elérni a külsőt, így csak egyirányú lehet a kapcsolat. Referenciával és pointerrel való hivatkozás esetén megoldható, hogy mindkét osztályban legyen egy hivatkozás a másikra. Core.h USART.h # include " USART.h" # include " Core.h" class Core { private : USART usart ; char r e g i s t e r s [ 2 5 6 ] ; public : void sendbyte ( char byte ) { usart >send ( byte ) ; void b y t e R e c e i v e d ( char b y t e ) { r e g i s t e r s [ 0 ] = b y t e ; ; class USART { private : Core core ; public :... void r e c e i v e ( ) { char data =... core >b y t e R e c e i v e d ( data ) ; ; GOND: a kereszthivatkozás így nem oldható meg, hiszen ez rekurzív fejlécállomány-hivatkozást okozna! Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 39 / 53

Tartalmazás Kétirányú kommunikáció II. Amennyiben egy külső fájlban definiált típusra csak mutató vagy referencia hivatkozik, akkor a fordítónak nem kell ismernie az adott típust, hiszen ilyenkor csak egy memóriacím kerül a hivatkozás helyére. Ha egy adott objektumnak hivatkozunk adattagjára vagy tagfüggvényére, akkor ismerni kell a típus deklarációját. Megoldás: 1 Az osztály fejlécállománya csak az a típusdefiníciót tartalmazza, a tagfüggvények definícióját ne (azokét semmiképpen, amikben a hivatkozott objektum tagfüggvényeit hívjuk). 2 Csak a metódusdefiníciókat tartalmazó fájlba szerkesszük be a másik típus fejlécállományát. 3 A fejlécállományokban a hivatkozott osztály(oka)t csak elődeklaráljuk. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 40 / 53

Tartalmazás Kétirányú kommunkáció III. A fejlécek Core.h USART.h class USART ; class Core { private : USART * usart ; char registers [256]; public : void sendbyte ( char byte ); void bytereceived ( char byte ); ; class Core ; class USART { private : Core * core ; public : void send ( char byte ); void receive ( char byte ); ; Az egyes fejlécállományok csak elődeklarálják a hivatkozott osztályokat. A kódban az adott típus csak mutató/referencia deklarációkban szerepel. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 41 / 53

Tartalmazás Kétirányú kommunkáció IV. A tagfüggvények definíciói Core.cpp # include " USART.h" void Core :: sendbyte ( char byte ) { usart ->send ( byte ); void Core :: bytereceived ( char byte ) { registers [0] = byte ; USART.cpp # include " Core.h" void USART :: send ( char byte ) {... void USART :: receive ( char byte ) { char data =... core -> bytereceived ( byte ); A definíciós fájlok beszerkesztik a hivatkozott osztályok fejléceit. Így az adott típus teljes ismeretében már történhetnek tagfüggvényhívások. Nincsen rekurzív beszerkesztés, hiszen a beszerkesztett fájlok nem tartalmaznak már visszahivatkozó include-ot. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 42 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók I. Előfordulhat, hogy egy osztály ugyanazt a hívást sokféle objektum felé meg szeretné tenni, ám ezeknek nincs közös őse. Tervezési elv is lehet, hogy csökkentve a függőségeket az osztályok között, nem hozunk létre közös őst egy (kevés) azonos aláírású függvény miatt. Megoldás: függvénymutatók bejegyzése az osztályokban. Egy függvénymutató egy egyszerű memóriacím, ahol egy adott aláírású függvény kódja kezdődik. Probléma: a tagfüggvényeknél ennél bonyolultabb a helyzet. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 43 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók II. Egy globális függvényre mutató pointer deklarációja: int (*fptr)(int) Ez a függvény tetszőleges olyan globális függvényre mutathat, ami egy int-et vár paraméterként és int a visszatérési értéke. A függvényhívás rajta keresztül pedig ugyanolyan, mintha egy egyszerű függvényt hívnánk: a függvényhívó operátort használjuk. int f( int i) { return 2 * i; int main () { int (* fptr )( int ) = f; std :: cout << fptr (5) << std :: endl ; return 0; Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 44 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók III. A tagfüggvényeknél a problémát az jelenti, hogy van egy implicit paraméterük a this pointer. Ennek helyére automatikusan behelyettesítődik a hívó objektum címe a tagfüggvényhíváskor: obj.tfv(5) Osztaly::tfv(&obj, 5) Ezért ha egyszerűen eltároljuk egy tagfüggvény címét, akkor még nem tudjuk meghívni, hiszen mindenképpen szükség van egy objektumra. Egy tagfüggvénymutatót csak objektummal együtt tárolhatunk el. Osztaly * objektum ; int ( Osztaly ::* tagfuggveny )( int ); Hívás: objektum->*tagfuggveny(5) Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 45 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók IV. Két probléma van: 1 a globális függvényekre és a tagfüggvényekre létrehozott mutatókat eltérően kell kezelni 2 a tagfüggvénymutatók típusa tartalmazza az osztályt, így nem tudunk osztályfüggetlen mutatót készíteni A megoldáshoz segítségül hívjuk a többalakúságot és a sablonokat. Elsődleges célunk az lesz, hogy többféle osztály tagfüggvényeit is be tudjuk jegyezni, de a bemutatott módszer lehetővé teszi a globális függvények használatát is. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 46 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók V. Mivel összetett viselkedést kell megvalósítani, osztályokat érdemes készíteni. Mivel kétféle viselkedésre van szükségünk, kell egy közös ős. Függvényhívást szeretnénk megvalósítani, ezért a közös tulajdonság az lesz, hogy függvényként hívható osztályaink lesznek. Ebben a példában egyféle függvényaláírást fogunk tudni kezelni. class base_function { public : virtual void operator ()( int ) const = 0; virtual ~ base_function () { ; A virtuális függvény feladata az egyes osztályokban az lesz, hogy a függvényhívást delegálja a megfelelő, mutatóval hivatkozott függvényhez/tagfüggvényhez. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 47 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók VI. Az globális függvények becsomagolása nagyon egyszerű: class plain_function : public base_function { private : void (* fptr )( int ); public : plain_function ( void (* fptr )( int )) : fptr ( fptr ) { ; virtual void operator ()( int i) const { fptr (i); Az osztály eltárol egy függvénypointert és a függvényhívó operátor által átvett értékkel meghívja a hivatkozott függvényt. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 48 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók VII. Tagfüggvények esetén ugyanez a feladat, csak ott egy objektumot és egy tagfüggvénymutatót kell eltárolni. template < typename T> class member_function : public base_function { private : T * object ; void (T ::* method )( int ); public : member_function (T * object, void (T ::* method )( int )) : object ( object ), method ( method ) { ; virtual void operator ()( int i) const { ( object - >* method )(i); Annak érdekében, hogy tetszőleges osztály tagfüggvényét el tudjuk tárolni, sablon-osztályt készítünk. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 49 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók VIII. Abban az osztályban, ahol a hivatkozásokat el szeretnénk helyezni, kell egy base_function mutató adattag, ami mindig a bejegyzett függvényt becsomagoló, dinamikusan létrehozott objektumra mutat. class module { private : base_function * registered_function ; public : module () : registered_function (0) { ~ module () { delete registered_function ;... void do_something ( int i) { std :: cout << " Calling registered function : "; (* registered_function )(i); ; A do_something metódus hívja meg az ős virtuális függvényén keresztül a megfelelő csomagoló osztályt, ami delegálja a hívást a tényleges függvényhez. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 50 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók IX. Készíteni kell egy-egy beregisztráló metódust globális függvényekhez és tagfüggvényekhez.... void register_function ( void (* fptr )( int )) { delete registered_function ; registered_function = new plain_function ( fptr ); template < typename T> void register_function (T * object, void (T ::* method )( int ) ) { delete registered_function ; registered_function = new member_function <T>( object, method );... Ezek lehetnek azonos nevűek, hiszen a függvények túlterhelhetősége ezt megengedi és mivel ugyanazt a feladatot látják el, ez logikus is. Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 51 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók X. Az osztály használata: class entity { public : void f( int i) { std :: cout << (i * 2) << std :: endl ; ; void fun ( int i) { std :: cout << " fun : " << i << std :: endl ; int main () { module m; m. register_function ( fun ); m. do_something (5) ; entity e; m. register_function (&e, & entity :: f); m. do_something (5) ;... Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 52 / 53

Tartalmazás Minimális függőség kialakítása függvénymutatók XI. Tovább bonyolíthatja a helyzetet, ha tetszőleges aláírású függvény bejegyzését szeretnénk lehetővé tenni. Erre a problémára a C++98 szabvány szerint csak meglehetően körülményes megoldást lehetett adni. A C++11 szabvány óta létezik szabványos függvény-csomagoló: az std::function. A fent bemutatott módszert használják a C++-ban eseménykezelésre. A SystemC TLM-ben is hasonló módon oldják meg a küldők és fogadók közötti kommunikációt (erről később lesz szó). Dr. Czirkos Zoltán, Nagy Gergely, Horváth Péter C / C++ áttekintés 53 / 53