Objektumok inicializálása Miskolci Egyetem Általános Informatikai Tanszék Objektumok inicializálása CPP4 / 1 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 CPP4 / 2 Adattagok inicializálása felsorolással 1. class szemely { // CPPEX17 // Most a példa kedvéért!! char* nev; int szulev; void kiir (void) {cout << " \n" << nev << szulev; Objektumok inicializálása CPP4 / 3
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 CPP4 / 4 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 CPP4 / 5 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 CPP4 / 6
Objektum tömbök - példa class szemely { char* nev; int szulev; 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 CPP4 / 7 Objektum tömbök - példa (folyt.) main() { szemely szulok[]={ szemely("kiss ", 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 CPP4 / 8 Osztály típusú adattagok 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 CPP4 / 9
Osztály típusú adattagok - példa class szemely { char* nev; int szulev; szemely (char* ki, int mikor) {... void kiir (void) {... Objektumok inicializálása CPP4 / 10 Osztály típusú adattagok - példa (folyt.) class gyerek { char* neve; int szuletett; szemely anya; 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 CPP4 / 11 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 CPP4 / 12
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 CPP4 / 13 Osztály típusú adattagok - példa (folyt.) main() { gyerek kisgyerek("toth imre", 1994,"Kiss Bea",1970); kisgyerek.kiir(); } Objektumok inicializálása CPP4 / 14 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 CPP4 / 15
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 CPP4 / 16 A másoló (copy( 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 CPP4 / 17 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 CPP4 / 18
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 CPP4 / 19 Tagobjektum inicializálása - példa class szemely { char* nev; int szulev; szemely (char* ki, int mikor){... szemely (const szemely& sz) {nev=new char[strlen(sz.nev)+1]; strcpy (nev, sz.nev); szulev = sz.szulev; void kiir (void) {... Objektumok inicializálása CPP4 / 20 Tagobjektum inicializálása - példa (folyt.) class gyerek { char* neve; int szuletett; szemely anya; // 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 CPP4 / 21
Tagobjektum inicializálása - példa (folyt.) class gyerek { char* neve; int szuletett; szemely anya; // 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 CPP4 / 22 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 CPP4 / 23 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 CPP4 / 24
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 CPP4 / 25 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 CPP4 / 26 Értékadó operátor - példa class szemely { char* nev; int szulev; // 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 CPP4 / 27
É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 CPP4 / 28