1 / 26

ÚVOD DO C++ 4

ÚVOD DO C++ 4. Pole, ukazatele a odkazy. 4. Pole objektů 4.1.Ukazatelé na objekty, použití 4.2. Ukazatel this 4.3. Dynamická alokace paměti - new - delete 4.4. Inicializace dynamicky alokovaného objektu

Download Presentation

ÚVOD DO C++ 4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ÚVOD DO C++ 4 Pole, ukazatele a odkazy

  2. 4. Pole objektů 4.1.Ukazatelé na objekty, použití 4.2. Ukazatel this 4.3. Dynamická alokace paměti - new - delete 4.4. Inicializace dynamicky alokovaného objektu 4.5. Dynamická alokace jednorozměrného pole 4.6. Odkazy v C++

  3. Pole objektů Objekty jsou proměnné obdobných vlastností jako v jazyku C. Pole objektů je určeno - velikostí pole - bázovým typem pole ( typem je třída ) Syntaxe: Deklarace pole objektů : Class Trida { int a; public: void nastav_a ( int n) { …… .void predej_a ( ) { ……….. } ; Int main() { Tridapole_objektu[5]; // deklarave pole objektů o 5_ti prvcích ……. }

  4. Do pole objektů je zapisována řídící proměnná cyklu pomocí fce nastav_a() a opět vypsána : */ #include<iostream> using namespace std; class Vzorek { // použit implicitní konstruktor a destruktor int a; public: void nastav_a( int n) { a=n;} int vypis_a() { return a;} }; int main() { int i; Vzorek pole_objektu[4]; //Deklarace pole objektů // Zápis do pole objektů: for( i=0;i<4; i++) pole_objektu [ i ].nastav_a( i ); /* Členská funkce nastav_a( i ); je volána pro každý prvek pole */ //Výpis pole objektů: for( i=0; i<4; i++){ cout << pole_objektu[i].vypis_a( ) << "\n"; } system(“pause”); return 0; }

  5. Inicializace pole objektů. Podmínkou pro provedení inicializace je explicitní konstruktor deklarovaný v typové třídě. Příklad inicializace pole objektů: class Vzorek { int a; public: // explicitní konstruktor: Vzorek ( int n) { a= n; } //členská funkce: int predej_a() { return a; } }; int main() { //Deklarace jednorozměrného pole s inicializací: Vzorek pole_objektu[4] ={ -1, -2, -3, -4 } ; int i; cout<<"Vypis pole objektu :\n"; for( i=0; i<4; i++ ){ cout << pole_objektu[i].predej_a() << ' '; } cout << "\n"; systém(“pause“); return 0; }

  6. Vícerozměrná pole objektu. Deklarace je stejná jako v C. Příklad dvojrozměrného pole a jeho inicializace : class Vzorek { int a; public: //konstruktor - podmínka pro provedení inicializace : Vzorek ( int n ) { a=n;} //členská funkce: int predej_a() { return a ;} }; int main() { //Deklarace dvojrozměrného pole s inicializací : Vzorek pole_objektu[4][2] = { 1, 2, 3, 4, 5, 6, 7, 8, }; int i; cout << "Vypis pole_objektu[4][2]:\n\n"; for( i=0; i<4; i++) { cout << pole_objektu[i][0].predej_a() << ' '; cout << pole_objektu[i][1].predej_a() << "\n"; } systém(“pause“); return 0; }

  7. Inicializace pole v případě použití konstruktoru s více parametry. Přebírá-li konstruktor více než jeden argument,je nutné k inicializaci pole použít při inicializaci standardní dlouhou formu. Tento formát inicializace lze použít i když objekt přebírá pouze jediný argument. Zkrácená forma je však v tomto případu pohodlnější. #include<iostream> using namespace std; class Vzorek { int a, b; public: //konstruktor : Vzorek ( int n, int m ) { a=n; b=m;} //členské funkce : int predej_a() { return a;} int predej_b() { return b;} };

  8. int main() { /* Inicializace je provedena přímým voláním konstruktoru Vzorek(n,m)*/ Vzorek pole_objektu[4][2] = { Vzorek(1, 2),Vzorek(3, 4), Vzorek(5, 6),Vzorek(7, 8), Vzorek(9,10),Vzorek(11,12), Vzorek(13,14),Vzorek(15,16) }; int i; cout << "Vypis pole_objektu[4][2]:\n\n"; for( i=0; i<4; i++){ cout << pole_objektu[i][0].predej_a() << ' '; cout << pole_objektu[i][0].predej_b() << "\n"; cout << pole_objektu[i][1].predej_a() << ' '; cout << pole_objektu[i][1].predej_b() << "\n"; } systém(“pause“); return 0; }

  9. 4.1. Ukazatelé objektu - použití Objekty mohou být dosažitelnépomocí ukazatele na objekt. Adresu objektu získáme použítím adresního operátoru & Použití ukazatele na objekt vyžaduje nahradit operátor tečka operátorem šipka V C++ platí stejně i aritmetika ukazatelů jako v C. ( inkrementace ukazatele způsobí přechod na nasledující prvek pole objektů ). Příklad : #include<iostream> using namespace std; class Vzorek { int a, b; public: /*konstruktormá dva parametry (n,m), proto bude inicializace provedena dlouhou formou */ Vzorek( int n, int m) { a = n; b=m; } // členské funkce: int predej_a() { return a;} int predej_b() { return b;} };

  10. int main() { //Při inicializaci je nutné použít dlouhou formu: Vzorek pole_objektu[4]= { Vzorek(1,2), Vzorek(3,4), Vzorek(5,6), Vzorek(7,8) }; int i; Vzorek *p_pole_objektu; p_pole_objektu = pole_objektu; /* název pole objektů obsahuje adresu prvního prvku pole objektů Výpis obsahu pole_objektu[ ] pomoci aritmetiky ukazatelů: */ cout<<"Vypis pole objektu pomoci aritmetiky "; cout << " ukazatelu\n"; for( i=0; i< 4; i++){ cout << p_pole_objektu -> predej_a() << ' '; cout << p_pole_objektu -> predej_b() << "\n"; /* inkrementace ukazatele - postup k dalšímu objektu */ p_pole_objektu ++; } system("Pause"); return 0; }

  11. 4.2. Ukazatel this ( pseudoproměnná ). Metoda musí být informována, s jakou instancí má pracovat. Proto je nestatickým metodám předáván implicitní, skrytý parametr ukazatel na aktuální instanci. Předává se automaticky včetně konstruktorů a destruktorů. Název pseudoproměnná získal this proto, že na rozdíl od proměnných, které definuje programátor, definuje pseudoproměnnou this překladač. Častěji má však název ukazatel this. Ukazatel this - je typu ukazatel na třídu, které je objekt instancí - ukazuje na aktuální objekt, kterému je zasílána zpráva V každém objektu je k dispozici ukazatel this na tento objekt a tento fakt si lze představit tak, že v každé třídě (př. class T_třída) je implicitně deklarován atribut T_třída *const this jehož hodnotu nemůžeme měnit !!!

  12. Příklad.: Objekt2 . f1_členská( ); f1_členská( ) předává automaticky ukazatel this na Objekt2, který aktivoval volání, protože f1() - je funkce členská, - není spřátelená - není označená static. . Příklad požití při odkazování na atribut n třídy T. Parametr metody nastav( int n) zakryje viditelnost atributu stejného jména: class T_trida{ int n; public: void nastav( int n); ..... } //end class void T_trida:: nastav( int n ) { this ->n = n; }

  13. #include<iostream> // demonstrace this #include<cstring> using namespace std; class Inventarni_zaznam { char polozka[80]; double cena_polozky; int skladovano_pocet; public: // konstruktor : Inventarni_zaznam( char *p_zdroj, double cena, int skl) { strcpy (this ->polozka, p_zdroj); // strcpy(polozka,p_zdroj); this ->cena_polozky =cena; // cena_polozky=cena; this ->skladovano_pocet = skl; //skladovano_pocet = skl; } //členská funkce: void zobraz(); }; // end třídy

  14. //Definice členské funkce: pokračování void Inventarni_zaznam::zobraz() { cout << "Nazev polozky: " << this ->polozka <<"\n"; //cout << "Nazev polozky: " << polozka <<"\n"; cout << "Cena :" << this ->cena_polozky << "Kc"<<"\n"; //cout << "Cena :" <<cena_polozky << "Kc"<<"\n"; cout << "Pocet kusu na sklade: "; cout << this ->skladovano_pocet<<"\n"; //cout << skladovano_pocet<<"\n"; } int main() { Inventarni_zaznam objekt("Budvar",25.70,54); objekt.zobraz(); system("Pause"); return 0;

  15. 4.3. Dynamická alokace - new a delete Funkce malloc( ) a free( ), známé z jazyka C pro alokaci a uvolnění paměti lze použít i v C++. Navíc lze požít v C++ nový způsob přidělování a uvolňování paměti pomocí funkcí new - protějšek malloc( ) delete - protějšek free( ) Uvedené funkce lze použít bez omezení, ( jsou to standardní funkce), ale použití new a delete v jazyce C++ je - bezpečnější - pohodlnější. Výhody používání new a delete: - new automaticky přiděluje dostatek paměti pro uložení objektu daného typu a proto není nutné používat fcisizeof(). - automaticky vrací ukazatel určeného typu, není nutné provádět přetypování - obě fce, delete i new mohou být přetěžovány - není nutné vkládat < cstdlib > - umožňují inicializovat dynamicky alokovaný objekt

  16. Dynamické proměnné v C++. Dynamické proměnné - paměť je jim přidělena až za běhu programu. Příkazem za běhu programu je jim přidělená paměť i uvolněna. Přidělení paměti - syntaxe : new typ_proměnné; Typ_proměnné - označení typu proměnné, pro kterou provádíme alokaci. Průběh: Operátor new vyčlení ve volné paměti místo potřebné pro alokaci daného typu a vrátí ukazatel na alokovanou paměť. Příklad alokace: int *p_i = new int ; Není-li dostatek paměti k provedení alokačního příkazu, vrátí new prázdný ukazatel nebo vygeneruje výjimku. Není-li vyjímka programem obsloužena, program bude ukončen. (závisí to na překladači ). Před použitím paměti je nutné otestovat hodnotu ukazatele, vráceného operátorem new, zda není prázdný ( selhání alokace ). Dynamicky přidělenou paměť pro proměnnou lze uvolnit použitím operátoru delete s argumentem ukazatel na přidělenou paměť. Syntaxe: delete p ;

  17. #include<iostream> using namespace std; int main( ) { int *p_int; p_int = new int; // alokace paměti pro integer //TEST PŘED POUŽITÍM ALOKOVANÉ PAMĚTI : if( !p_int ) { cout << "Chyba pri alokaci pameti\n"; return 1; } //Zapis do alokovane pameti: *p_int = 100; cout << "Vypis hodnoty v alokovane pameti "; cout << "*p_int :"<< *p_int <<"\n"; //Uvolneni pameti: delete p_int; system("Pause"); return 0; }

  18. Inicializace dynamicky alokovaných proměnných a objektů pomocí operátoru new. Syntaxe inicializace proměnné : ukazatel = new jméno_typu( parametr_inicializace ) Operátor new 1)vyčlení z volné paměti prostor pro vytvoření instance odpovídající typu proměnné 2) uloží do něj honotou uvedenou jako parametr_inicializace 3) vrátí adresu alokované paměti - viz ukazatel. Příklad: /* Program přidělí dynamicky paměť pro proměnnou typu integer a zároveň provede její inicializaci na hodnotu 9.*/ #include<iostream> using namespace std; int main() { int *p_int; p_int new int(9(); ………………. …………….

  19. Příklad inicializace proměnné, new mápouze jeden parametr: int main() { int *p_int; //Alokace paměti pro proměnnou integer - inicializace hodnotou 9: cout<<"Alokace pameti pro integer byla provedena "; cout<<"prikazem p_int = new int( 9 );\n"; p_int = new int ( 9 ); if(!p_int ) { cout << "Chyba alokace pameti\n"; return 1; } cout << "Vypis hodnoty dereferenci *p_int :"; cout << *p_int << "\n"; // Uvolnění paměti delete p_int; systém(“pause”); return 0; }

  20. Dynamická alokace objektu, inicializace s předáním více parametrů. Syntaxe inicializace objektu : ukazatel = new jméno_objetového_typu( parametry_inicializace ) parametry_inicializace – jsou parametry konstruktoru Příklad inicializace dynamicky vytvořeného objektu, dva inicializační parametry: #include<iostream> using namespace std; class Vzorek { int i,j; public: //konstruktor s parametry - inicializace: Vzorek( int a, int b) { i=a; j= b;} //clenska funkce: int predej_soucin() { return i*j; } int vypis_i () { return i;}; int vypis_j () { return j;}; }; pokračování

  21. pokračování int main() { Vzorek *p_objekt; /*Alokace objektu s inicializaci: automaticky je volán konstruktor a ten provede inicializaci hodnotou 6 a 5 */ p_objekt = new Vzorek(6,5); //Test úspěšnosti alokace: if(!p_objekt) { cout << "Chyba alokace pameti\n"; return 1; } cout << "Soucin je : " << p_objekt -> predej_soucin(); //Uvolněni paměti: delete p_objekt; systém(“pause”); return 0; }

  22. Dynamicka alokace pole (s použitím operátoru new). Pole, které je dynamicky alokováno, nelze při vytvoření inicializovat !!!! Syntaxe: Pro vytvoření jednorozměrného pole bude mít operátor new formát : ukazatel = new typ_pole [ velikost_pole ] ; Pro uvolnění tohoto dynamicky alokovaného pole bude mít operátor delete formát : a) pro starší překladače: delete [ velikost_pole ] ukazatel; b) pro moderního překladače : delete [ ]ukazatel; Překladač zavolá destruktor pro každý prvek pole.

  23. Příklad - vytvoření dynamického pole objektů: /* Vytvoření dynamického pole 8-mi objektů, atributy objektů zapsány pomocí členské fonkce nastav_ij( ) : */ class Vzorek { int i,j; public: void nastav_ij( int a, int b){ i=a; j=b; } int predej_soucin() { return i*j;} }; int main() { Vzorek *p_pole; int i; p_pole = new Vzorek[ 8 ]; // zde provédt test úspěšnosti alokace //Zapis do pole objektů, hodnotaj = i : for( i=0; i< 8; i++){ p_pole[i].nastav_ij(I,I); } delete[] p_pole; getchar(); return 0; }

  24. Příklad - předchozí verze programu doplněná o destruktor.Ten je volán pro každý prvek pole, kterým je objekt, tedy volán 10-krát. /* Vytvoření dynamického pole 10-ti objektů : když je uvolňováno pole, je postupně volán destruktor každého objektu t.j.10-krat */ #include<iostream> using namespace std; class Vzorek { int i,j; public: //destruktor: ~ vzorek() { cout <<" Destrukce..... \n"; } //členské funkce: void nastav_ij( int a, int b){ i=a; j=b; } int predej_soucin() { return i*j;} }; int main() { Vzorek *p_pole; int i; //Alokace pole: p_pole = new vzorek[10]; pokračování

  25. //Zapis do pole, j = i : ……. //Vypis pole:……… …………. delete[] p_pole; //volá pro každýprvek pole, kterým je objekt, destruktor return 0; } Výpis programu: Soucin [ 0 ] = 0 Soucin [ 1 ] = 1 Soucin [ 2 ] = 4 . Soucin [ 9 ] = 81 destruktor je volán 10 krát : Destrukce..... Destrukce..... Destrukce..... Destrukce..... Destrukce..... Destrukce..... Destrukce..... Destrukce..... Destrukce..... Destrukce.....

  26. Odkazy

More Related