C++ programozási nyelv Konstruktorok Gyakorlat Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2004. október A C++ programozási nyelv Soós Sándor 1/17
Tartalomjegyzék A házi feladat tanulságai 1. eset 2. eset (eset02.dsw) 3. eset 4. eset Tömbök 1) Statikus (eset04_1.dsw) 4. eset Tömbök 2) Fix méretű, dinamikus 4. eset Tömbök 3) Változó méretű, dinamikus 5. eset - Mutatótömbök Példa mutatótömbökre Kompozíció, beágyazás Hogyan viselkednek a tagobjektumok? (tagobj1.dsw) A C++ programozási nyelv Soós Sándor 2/17
A házi feladat tanulságai A szorzás és az osztás nem felcserélhető, ha egész számok körében dolgozunk. túlcsordulás alulcsordulás koltseg = (kilometer / 100) * fogyasztas * benzinar; a kifejezés kiértékelése attól függ, hogy milyen típusúak a változók A C++ programozási nyelv Soós Sándor 3/17
1. eset Mi történik akkor amikor a következő kódot írjuk a programba? Valami v; Lefoglalja a memóriát Lefuttatja a konstruktort Mi történik, ha a Valami osztályban nincsen default konstruktor? Valami *vp; Létrehoz egy pointert Nem fut konstruktor vp = &v; // a v változó címét tesszük vp-be A C++ programozási nyelv Soós Sándor 4/17
2. eset (eset02.dsw) { Valami v, *vp; v.x = 7; vp = &v; delete vp; // formailag helyes, de hibás, nem new-val // foglalt területet szabadít fel!!! } A C++ programozási nyelv Soós Sándor 5/17
3. eset vp = new Valami[3]; delete [] vp; Ehhez kell legyen a Valamiben default konstruktor! Vagy mi hozzuk létre, vagy engedjük, hogy a C++ hozza létre. A C++ programozási nyelv Soós Sándor 6/17
4. eset - Tömbök 1) Statikus (eset04_1.dsw) A tömb nem ismeri a saját méretét, de kiszámítható: Valami t1[10]; double dt[3]; int i; for ( i = 0; i < sizeof(dt); i++ ) dt[i] =0; // sizeof visszaadja a változó méretét bájtban!!! helyesen: for ( i=0; i<(sizeof(dt) / sizeof(double)); i++ ) dt[i] =0; vagy: for ( i=0; i<(sizeof(dt) / sizeof(dt[0])); i++ ) dt[i] =0; A C++ programozási nyelv Soós Sándor 7/17
4. eset - Tömbök 1) Statikus (eset04_1.dsw), folyt A tömb mérete kiszámítható a sizeof operátorral, de... void f( double P[] ) { for (int i=0; i<sizeif(p)/sizeof(double); i++ ) P[i] = 0; // sizeof(p): a pointer méretét adja vissza } A fv.-ben nem tudom a tömb méretét, vagy át kell adni a méretet, vagy lezárót kell használni Egy tömb neve önmagában is cím, kiírható elé az &, de el is hagyható. A C++ programozási nyelv Soós Sándor 8/17
4. eset - Tömbök 2) Fix méretű, dinamikus double *dp; int n, n_adat;... n=3;... dp = new double[n]; A tömb mérete 2 dolgot jelent: a teljes mérete, a hasznos adatok száma A C++ programozási nyelv Soós Sándor 9/17
4. eset - Tömbök 3) Változó méretű, dinamikus Ehhez ugyanarra van szükség, mint az előző esetben. double *dp; int n, n_adat; A növeléshez új tömböt foglalok átmásolom az adatokat a régi tömböt felszámolom Ami összetartozik, azt tegyük egy osztályba! A C++ programozási nyelv Soós Sándor 10/17
5. eset - Mutatótömbök Itt is megkülönböztethetjük a 4. eset alatti 3 alesetet. 1) Statikus Valami *vt[3]; int n_adat; Könnyen mozgathatóak az elemek, pl. rendezés Akár több mutató tömb is mutathat ugyanazokra az elemekre. Ekkor is felmerül a "gazdája-nem gazdája probléma! Mi is volt ez? A C++ programozási nyelv Soós Sándor 11/17
Példa mutatótömbökre Valami v1 Valami *p[8] [0] [1] [2] [3] [4] [5] = NULL [6] = NULL [7] = NULL Valami v2 Valami v3 Valami v4 [0] Valami *q[8] [1] [2] [3] [4] [5] = NULL [6] = NULL [7] = NULL Valami v5 A C++ programozási nyelv Soós Sándor 12/17
Kompozíció, beágyazás Nem szerencsés túl sok adatot egymás mellett tárolni egy strukturában. Az összetartozó adatokat fűzzük össze egy-egy kisebb struktúrába! Ezeket nevezzük tagobjektumoknak. Például emberek adatait szeretnénk nyilvántartani: Név Otthoni telefon Mobiltelefon Vezetéknév Keresztnév Előtag (Dr, Prof, Id, Ifj,...) Lakcím Irányítószám Város Utca Ideiglenes lakcím Irányítószám Város Utca Hogyan lenne célszerű csoportosítani az adatokat? Körzetszám Hívószám Munkahely A C++ programozási nyelv Soós Sándor 13/17 Cégnév Irányítószám Város Utca Körzetszám Hívószám Munkahelyi telefon Körzetszám Hívószám Mellék
Hogyan viselkednek a tagobjektumok? class Tag{ public: Tag() { printf("tag::tag\n"); } }; class Valami{ public: Tag t; }; int main() { Valami v; return 0; } // Kiírja: Tag::Tag A C++ programozási nyelv Soós Sándor 14/17
Hogyan viselkednek a tagobjektumok? A Valami generált konstruktora meghívja a tagobjektumok konstruktorait. Gond van, ha valamiért nem tud lefutni egy beágyazott tag konstruktora! Ha a Tag-ban nincs konstruktor, akkor létrehozza a fordító. Ha tudja! class Tag{ public: Tag( int x ) { printf("tag::tag(x)\n"); } }; Így gond lesz, mert nem tudja legyártani a default konstruktort. A C++ programozási nyelv Soós Sándor 15/17
Hogyan viselkednek a tagobjektumok? (tagobj1.dsw) class Tag{ public: Tag() { printf("tag::tag\n"); } }; class Valami{ public: Valami() { printf("valami::valami\n"); } Tag t; }; Ekkor is lefut a Tag konstruktora, milyen sorrendben? Tag::Tag Valami::Valami A destruktorok éppen fordítva! A C++ programozási nyelv Soós Sándor 16/17
Hogyan viselkednek a tagobjektumok? Mi történik ebben az esetben? class Valami{ public: Valami() { printf("valami::valami\n"); } Tag *tp; }; Hogyan kezelhetjük ezt a pointert? Ismét a gazdája-nem gazdája kérdéshez jutunk. A C++ programozási nyelv Soós Sándor 17/17