280 likes | 431 Views
Objektumok inicializálása. Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék. Tartalom. public adattagok inicializálása felsorolással k onstruktor o bjektum tömbök o sztály típusú tagok t agonkénti inicializálás i nicializálás a származtatás során.
E N D
Objektumok inicializálása Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék Objektumok inicializálása
Tartalom • public adattagok inicializálása felsorolással • konstruktor • objektum tömbök • osztály típusú tagok • tagonkénti inicializálás • inicializálás a származtatás során Objektumok inicializálása
Adattagok inicializálása felsorolással 1. class szemely {// CPPEX17 public:// Most a példa kedvéért!! char* nev; int szulev; public: void kiir (void) {cout << " \n" << nev << szulev; }; }; Objektumok inicializálása
Adattagok inicializálása felsorolással 2. main() { szemely valaki = {"todor", 1937}; valaki.kiir(); } • Analóg a struktúrák inicializálásával Objektumok inicializálása
Inicializálás konstruktorral Már ismert konstrukció Megjegyzések: • Több konstruktor is megadható ez függvény overloading, tehát a fordító a megadott paraméter szignatúra alapján választ • private konstruktor: csak a tagfüggvények és a friend osztályok érhetik el. • protected konstruktor: csak a leszármazottés a friend osztályok érhetik el Objektumok inicializálása
Objektum tömbök • Alapeset: a tömb minden elemére meghívódik a default konstruktor (amely átdefiniálható!) • Inicializációs lista: a lista minden eleme egy konstruktor hívás kijelölése • Egy paraméteres konstruktor esetén a paraméter megadása elegendő • Ha a lista kevesebb elemet tartalmaz, mint a tömb, a maradék elemekre a default konstruktor hívódik meg • Dinamikusan deklarált tömb esetén (new) a default kontruktor hívódik meg minden elemre. Objektumok inicializálása
Objektum tömbök - példa class szemely { char* nev; int szulev; public: szemely (char* ki, int mikor) {nev = new char [strlen(ki) + 1]; strcpy(nev, ki); szulev = mikor; } void kiir (void) {cout << " \n" << nev << szulev; } }; Objektumok inicializálása
Objektum tömbök - példa (folyt.) main() { szemely szulok[]={ szemely("Kiss Lajos", 1950), szemely("Kiss Bea",1955)}; szulok[0].kiir();szulok[1].kiir(); szemely nagyszulok[2]={ szemely("Nagy Bela", 1930) }; //nagyszulok[1].kiir(); hibás! } Objektumok inicializálása
Osztály típusú adattagok Tisztázandó kérdések: • Konstruktorok végrehajtási sorrendje • Először a tagosztály(ok) • Utána a tartalmazó osztály • A szabály rekurzív módon ismétlendő, ha szükséges • Paraméter átadás a tagosztály konstruktorának • Taginicializációs lista: a tartalmazó osztály definíciójának argumentumlistája után vesszővel elválasztott lista • Az alaptípusú adattagok is megjelenhetnek a listán Objektumok inicializálása
Osztály típusú adattagok - példa class szemely { char* nev; int szulev; public: szemely (char* ki, int mikor) { .... }; void kiir (void) { .... }; }; Objektumok inicializálása
Osztály típusú adattagok - példa (folyt.) class gyerek { char* neve; int szuletett; szemely anya; public: gyerek (char* nev, int ev, char* anyaneve, int anyaszuleve) : anya (anyaneve,anyaszuleve) {neve = new char[strlen(nev)+1]; strcpy(neve, nev); szuletett = ev; }; Objektumok inicializálása
Osztály típusú adattagok - példa (folyt.) // Másik lehetséges változat // gyerek (char* nev, int ev, // char* anyaneve, int anyaszuleve) // :anya (anyaneve,anyaszuleve), // szuletett(ev) // { // neve = new char[strlen(nev)+1]; // strcpy(neve, nev); // }; Objektumok inicializálása
Osztály típusú adattagok - példa (folyt.) void kiir (void) {cout << " \nGyerek neve, szuletesi eve:" << neve << szuletett; cout << "\nAnyja neve,szul. eve:"; anya.kiir(); }; }; Objektumok inicializálása
Osztály típusú adattagok - példa (folyt.) main() { gyerek kisgyerek("Toth imre", 1994,"Kiss Bea",1970); kisgyerek.kiir(); } Objektumok inicializálása
Tagonkénti inicializálás • Egy objektum inicializálása azonos típusú másik objektummal • Ekkor nincs hagyományos konstruktorhívás! • Nem azonos az objektumok közötti értékadással. • Két fázisa: • Létrejön az új objektum • Automatikus kezdőértékadás történik Objektumok inicializálása
Tagonkénti inicializálás előfordulásai • közvetlen inicializálás • érték szerint átadott osztály típusú paraméter • osztály típusú viszatérési érték • Egyéb, közvetett módon létrejövő ideiglenes objektumok (konverzió, kifejezés kiértékelésének részeredménye, kivétel objektum stb.) A fentiekből következik: • Soha nem lehetünk biztosak benne, hogy a programban nem történik ilyen inicializálás! Objektumok inicializálása
A másoló (copy) konstruktor • A fordítóprogram az X osztály objektumainak tagonkénti inicializálására a X::X(const X&) speciális konstruktort (copy konstruktort) hívja meg. • Ennek alapértelmezése: tagonkénti inicializáció • Ez nem mindig megfelelő, ezért saját verzió definiálható • Saját copy konstruktor esetén speciális szabályok Objektumok inicializálása
Tagobjektum és a copy konstruktor Két eset vizsgálandó • A tartalmazó osztálynak nincs copy konstruktora: ekkor alapértelmezés szerint tagonkénti inicializálás történik minden adattagra, azaz • A tag objektum a copy konstruktorával inicializálódik, ha rendelkezik ilyennel • A tag objektum az alapértelmezés szerinti tagonkénti értékadással inicializálódik egyébként Objektumok inicializálása
Tagobjektum és a copy konstruktor (folyt.) • A tartalmazó osztálynak van copy konstruktora: nem az alapértelmezés szerinti inicializálás történik • A tartalmazó osztály copy konstruktora köteles gondoskodni a tagobjektumok inicializálásáról, taginicializációs listával • Ha nincs a listán egy tagobjektum, akkor az alapértelmezés szerinti (tagonkénti) inicializálás történik, akkor is, ha a tagosztálynak van copy konstruktora! Objektumok inicializálása
Tagobjektum inicializálása - példa class szemely { char* nev; int szulev; public: szemely (char* ki, int mikor){...}; szemely (const szemely& sz) {nev=newchar[strlen(sz.nev)+1]; strcpy (nev, sz.nev); szulev = sz.szulev; }; void kiir (void){ ... }; }; Objektumok inicializálása
Tagobjektum inicializálása - példa (folyt.) class gyerek { char* neve; int szuletett; szemely anya; public: // Normál konstruktor gyerek (char* nev, int ev, char* anyaneve, int anyaszuleve) : anya (anyaneve,anyaszuleve) { neve = new char[strlen(nev)+1]; strcpy(neve, nev); szuletett = ev; }; Objektumok inicializálása
Tagobjektum inicializálása - példa (folyt.) class gyerek { char* neve; int szuletett; szemely anya; public: // Másik konstruktor gyerek (char* nev, int ev, szemely anyja): anya (anyja) { neve = new char[strlen(nev)+1]; strcpy(neve, nev); szuletett = ev; }; Objektumok inicializálása
Tagobjektum inicializálása - példa (folyt.) // Helytelen copy konstruktor gyerek ( const gyerek& gy) {neve = new char [strlen(gy.neve)]; strcpy (neve, gy.neve); szuletett = gy.szuletett; // Ez a hibás, mert nem copy konstruktorral inicializálódik!! anya = gy.anya;}; Objektumok inicializálása
Tagobjektum inicializálása - példa (folyt.) // A helyes valtozat (explicit // inicializalassal): gyerek ( const gyerek& gy): anya(gy.anya) {neve = new char [strlen(gy.neve)]; strcpy (neve, gy.neve); szuletett = gy.szuletett; }; Teljes verzió: CPPEX22.CPP Objektumok inicializálása
Inicializálás a származtatás során • A származtatott osztálynak nincs copy konstruktora • Alapmódszer a tagonkénti inicializálás • Az a bázisosztály, amelynek van copy konstruktora, azzal inicializálódik • A származtatott osztálynak van copy konstruktora • A származtatott osztály copy konstruktorának kell meghívnia a bázisosztály copy konstruktorát, ha van • Egyébként tagonkénti inicializálás, akkor is, ha a bázisosztálynak van copy konstruktora Objektumok inicializálása
Objektumok közötti értékadás • A fordító az azonos (X) típusú objektumok közötti értékadást a const X& operator= (const X&) tagfüggvénnyel végzi. • Alapértelmezése: tagonkénti értékadás • Saját verzió definiálható • Ha a copy konstruktorból saját verzió szükséges, akkor az értékadás operátorból is! Objektumok inicializálása
Értékadó operátor - példa class szemely { char* nev; int szulev; public: // Egyszerű konstruktor szemely (char* ki, int mikor); // Copy konstruktor szemely (const szemely& sz); // Értekadás const szemely& operator=(const szemely& sz); void kiir (void) const; }; Objektumok inicializálása
Értékadó operátor - példa (folyt.) const szemely& szemely::operator=(const szemely&sz){ if (this != &sz) { // Nem azonosak delete [] nev;// Regi ertek torlese nev = new char [ strlen(sz.nev)+1 ]; strcpy (nev, sz.nev); szulev = sz.szulev; } return *this; }; Objektumok inicializálása