Programozás II. 3. Gyakorlat C++ alapok
I/O műveletek #include <iostream> cout C-s megfelelője: stdio.h Alapvető input/output műveleteket tartalmazza cout Alapértelmezett kimenetre írhatunk vele stream (bájtok sorozata), melyeket << operátorral „köthetünk össze” cout << ”Hello World” << „!”;
I/O műveletek cerr cin Alapértelmezett hibakimenetre írhatunk vele. cout-hoz hasonló működés: cerr << „Hiba” << „…”; cin Alapértelmezett bementről olvas, változó típusának megfelelő értéket >> operátorral használható, akár több beolvasásra is: int x, y; cin >> x >> y;
C, C++ főbb különbségei C++ objektumorientált Névterek (namespace) Programjainkat, főleg nagyobb rendszerek esetében ún. névterekbe rendezhetjük. Hierarchikus tárolási mód, névtéren belül is létrehozható névtér. using parancs segítségével kijelölhető, mely névtere(ke)t szeretnénk használni. Pl.: using namespace std; vagy std::cout; (részletek előadáson)
C, C++ főbb különbségei Default paraméterek Függvények paramétereinek alapértelmezett értéket is adhatunk. Ezeknek a paramétereknek a paraméterlista hátulján kell lenniük! Ha kevesebb paraméterrel hívjuk a függvényt, az alapértelmezettek megkapják az előre beállított értéket. int Nagyobb (int a, int b = 0) { if (a < b) return b; else return a; } int x = nagyobb (2, 3); // x = 3 int y = nagyobb (2); // y = 2, ugyanez lenne: nagyobb(2, 0)
C, C++ főbb különbségei Egysoros comment Ciklusváltozó inicializálása C-ben csak több soros comment létezett: /* … */ C++-ban bevezették az egysoros commentet: //comment Ciklusváltozó inicializálása C-ben a for ciklusban használt változókat előre inicializálni kellett. C++-ban lehetséges a for cikluson belül inicializálni: for ( int i=0; i < 10; i ++ ) { // blokk } Ez a változó csak a for ciklus blokkjában létezik.
C, C++ főbb különbségei bool típus C-ben 0 = false, true = minden más C++-ban létezik bool típus, mely true/false értéket vehet fel bool igaz = true; //értéke: 1 bool hamis = false; //értéke: 0 További különbségek előadáson…
Osztály létrehozása class kulcsszóval definiáljuk az osztályt utána az osztály nevét kell megadni { } – blokkban definiáljuk az osztály adattagjait, függvényeit, stb… Fontos, hogy az osztályt egy ; jel zárja! Példa: class SimpleClass { //… };
Láthatóságok Az osztályok adattagjainak és függvényeinek kívülről való elérhetőségét szabályozhatjuk. private: ez az alapértelmezett láthatóság. Csak osztályon belül hivatkozhatunk rá protected: osztályon belül, és származtatott osztályokból érhető el public: bárhonnan elérhető Láthatóság megadása: megadjuk a láthatóságot, majd egy kettőspont (:) karaktert teszünk. Minden tag, amit ez után definiálunk, ezt a láthatóságot fogja megkapni.
Láthatóságok Példa: class SimpleClass { private: int a; public: int b; int c; protected: int d; };
Konstruktor A konstruktor az a speciális metódus, amely az osztály példányosításánál hívódik meg. Alapesetben itt adhatunk értéket az adattagjainknak, dinamikus változóinknak itt foglalhatunk helyet, stb. Nevének meg kell egyezzen az osztály nevével. Nem lehet visszatérési értéke. Egy osztály rendelkezhet több konstruktorral is, de azoknak különbözniük kell paraméter listában. A paraméter nélküli konstruktort default konstruktornak nevezzük. Ha az osztálynak nincs konstruktora, akkor a fordító automatikusan létrehoz egy defualt-ot.
Konstruktor Példa: class OneParameter { private: int m_iParameter; public: OneParameter() { //default m_iParameter = 0; } OneParameter( int a ) { //paraméteres m_iParameter = a; };
Destruktor Speciális függvény, mely az objektum törlésénél hívódik meg. Általában ide teszik a memória felszabadító, file lezáró, stb kódokat. Neve megegyezik az osztály nevével, plusz a neve elé kell tenni egy ~ jelet. Nem lehet visszatérési értéke és paramétere!
Destruktor Példa: class OneParameter { private: int m_iParameter; public: OneParameter() { //default konstruktor m_iParameter = 0; } OneParameter( int a ) { //paraméteres konstruktor m_iParameter = a; ~OneParameter() { //destruktor //Üres blokk, nincs dinamikusan foglalt erőforrásunk melyet fel kellene szabadítani };
Destruktor Példa: class OneParameter { private: int m_iParameter; public: OneParameter() { //default konstruktor m_iParameter = 0; } OneParameter( int a ) { //paraméteres konstruktor m_iParameter = a; ~OneParameter() { //destruktor //Üres blokk, nincs dinamikusan foglalt erőforrásunk melyet fel kellene szabadítani };
this pointer Az aktuális objektumra mutató pointer. Mivel pointer, ezért a -> operátorral kell hivatkozni az adattagokra és metódusokra. Jó példa használatára, mikor egy függvény paraméter listájában egy változónak a neve megegyezik egy member adattag nevével, ilyenkor a thisel tudunk különbséget tenni.
this pointer Példa: class OneParameter { private: int a; public: OneParameter( int a ) { //paraméteres konstruktor this->a = a; /*paraméter neve megegyezik egy osztályon belüli változó nevével. Ekkor a this pointer egyértelműsíti, melyiket szeretnénk használni*/ } };
Objektum példányosítás Objektumot hozhatunk létre a stack-en és a heap-en is. Ha a stack-en hozzuk létre, akkor élettartalma az aktuális blokk végéig tart, memória felszabadítása automatikus. Ha a heap-en hozzuk létre, akkor az élettartalma addig tart, ameddig a programozó ki nem törli. Ebben az esetben egy pointerrel mutatunk az objektumra.
Objektum példányosítás Stack-en, default konstruktorral: OneParameter first; Stack-en, paraméteres konstrukorral: OneParameter second( 2 ); Heap-en, default konstruktorral: OneParameter* third = new OneParameter; Heap-en, paraméteres konstrukorral: OneParameter* fourth = new OneParameter( 2 );
Delete Amit new-val lefoglaltunk, azt delete-vel ki is kell törölni (nincs GarbageCollector, mint Java-ban). példa: delete third; delete fourth;
Forrás és header fájl Az osztályok definíciós részének nem kellene (szabadna) implementációs részt tartalmazniuk (átláthatóság,kereskedelem), ezért a definíciót és az implementációt érdemes külön forrás file- okban tárolni. Ún. header fájlokban (valami.h) tároljuk osztályunk tagjainak definícióit Az implementációt egy másik fájlban (valami.cpp) írjuk meg Példa: vector osztály