Klase i pointeri

1

Klase i pointeri

offline
  • Nom  Male
  • Građanin
  • Pridružio: 17 Nov 2004
  • Poruke: 168
  • Gde živiš: Shanghai, China

Peca se zali da nema ko da ga odmeni - pa evo, probacu sa jednom kratkom lekcijom (koga zanima - ovo podrazumeva da znate sta su klase i pointeri u c++ -u).

U slucaju da je potreba da imate dinamicki alociran / dealociran niz nekih objekata u memoriji (na primer, custom-draw dugmici na ekranu, njihov broj i labele zavise od neceg) lako dodavanje / brisanje moze da se uradi na sledeci nacin:

Prvo, definicija klase:
class C_dugme { private:     (...) public:     C_dugme(....paramteri....);     ~C_dugme();     (...) };

Zatim definisemo novi tip:
typedef C_dugme *pC_dugme;

Ovim imamo novi tip koji je u stvari pointer C_dugme.

Princip je da se radi sa pointerima na pointere tj. sledece:
pC_dugme *Dugme; Dugme = new pC_dugme[broj_dugmica]; // sa ovim je definisana lista pointera na pointere // sa ovim inicijalizujem svako dugme posebno // konstruktoru mogu biti prosledjeni parametri kao sto su labela, velicina, pozicija, boja, ikonica i sl. for(int i=0;i<broj_dugmica;i++)     Dugme[i] = new C_dugme(...parametri...); // p.s. pocetno stanje moze da bude i Dugme = NULL tj. broj_dugmica = 0; // U tom slucaju, inicijalno dodavanje novih dugmica je opisano kasnije


Kad dodajes novo dugme, uradis lako sledece (pod uslovom da je lista vec popunjena nekim dugmicima):
pC_dugme *tmp = new pC_dugme[broj_dugmica]; for(int i=0;i<broj_dugmica;i++)     tmp[i] = Dugme[i]; // sa ovim cuvamo pointere na pointere delete[] Dugme; Dugme = new pC_dugme[broj_dugmica+1]; for(int i=0;i<broj_dugmica;i++)     Dugme[i] = tmp[i]; // sa ovim vracamo sacuvane pointere delete[] tmp; tmp = NULL; // sa ovim predhodnim smo lako dodali novi pointer na pointer u listi, BEZ kopiranja memorije // sa ovim dole inicijalizujemo dodati dugmic Dugme[broj_dugmica] = new C_dugme(...parametri...) broj_dugmica ++;

Isti princip vazi i za brisanje - sve bez memcpy i slicnih vratolomija.

Samo obratite paznju da SVE sto je alocirano sa new mora da ima svoj delete (odnosno sa new...[] svoj delete[] )

Znaci brisanje ide ovako:
if(!broj_dugmica) return; // nema brisanja ako ih nema vise dugme_koje_brisemo = (.... index zeljenog dugmeta ....) ; // ovde bi dobro dosla i sledeca provera: if(dugme_koje_brisemo<0 || dugme_koje_brisemo>broj_dugmica-1) return; // znaci da nije validan index trazenog dugmeta - onda pali napolje broj_dugmica--; pC_dugme *tmp = new pC_dugme[broj_dugmica]; // privremeni pointeri, da sacuvamo one koje necemo da brisemo iz liste int index = -1; // ovo nam sluzi za trenutni index tmp-a for(int i=0;i<broj_dugmica+1;i++) // +1 jer je br. dugmica vec smanjen {     if(i!=dugme_koje_brisemo) // dugme_koje_brisemo je index zeljenog   dugmeta     {         index++;         tmp[index] = Dugme[i]; // sa ovim cuvamo pointere na preosalu dugmad     }     else     {         delete Dugme[i]; // brisemo alocirano dugme         Dugme[i] = NULL; // posle svakog brisanja, ovo uvek obavim     } } delete[] Dugme; // sad smo sacuvali preostale dugmice, ovi mogu da se brisu Dugme = new pC_dugme[broj_dugmica]; // i napravimo nove for(int i=0;i<broj_dugmica;i++)     Dugme[i] = tmp[i]; // prespojimo ih nazad delete[] tmp; tmp = NULL; // i brisemo privremene pointere

I to je to!

Obratite paznju da ako je ostalo samo jedno dugme tj. broj_dugmica == 1 pre brisanja, brisnje ide:

delete Dugme[0]; Dugme[0] = NULL; delete[] Dugme; Dugme = NULL; broj_dugmica = 0;

Ovde i Dugme mora da bude NULL jer u slucaju da neka f-ja pokusa da ga koristi, NULL joj govori da ne postoji - time sprecavate prckanje po memoriji koja je dealocirana.

Isto tako, prilikom dodavanja prvog dugmeta, u slucaju da je Dugme == NULL tj. broj_dugmica == 0 pre dodavanja novog dugmeta, onda ide ovako:
broj_dugmica ++; Dugme = new pC_dugme[1]; Dugme[0] = new C_dugme(...parametri....);

Ovde nema potrebe za tmp pointerima.

Citat:
Citat:
Izvinjavam se zbog dodatnog editovanja poruke - al navikao sam na TAB pri kucanju koda a ovde to ima drugi efekat Wink

Evo, sad sam stavio onaj code Wink


Poz. svima!



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Peca  Male
  • Glavni Administrator
  • Predrag Damnjanović
  • SysAdmin i programer
  • Pridružio: 17 Apr 2003
  • Poruke: 23208
  • Gde živiš: Niš

oni koji ne znaju sta su pointeri i sta su klase - nista nece shvatiti Smile

po meni, trebalo bi krenuti od samog pocetka, i to prvo od C-a, da ljudima pokazemo kako program linearno funkcionise, sta su procedure, funkcije, promenljive.....

ali ok, trebace i ovo nekom, ko je poceo da uci C++
ako nekome nesto nije jasno od ovoga sto je Nom napisao, neka pita.

--------------

inace, tab mozes da koristis samo ako kod stavis izmedju code tag-a.
ovako:
[code]    test [/code]



offline
  • Nom  Male
  • Građanin
  • Pridružio: 17 Nov 2004
  • Poruke: 168
  • Gde živiš: Shanghai, China

@Peca

'fala za  ...

offline
  • Pridružio: 18 Apr 2003
  • Poruke: 5001
  • Gde živiš: Beograd

ja sam mislio da kad je nesto alocirano sa new [] da se to brise sa "delete [] promenljiva" da ne mora pojedinacno

i drugo zar ono dodavanje dugmeta ne bi moglo ovako
pC_dugme *tmp = new pC_dugme[broj_dugmica+1]; for(int i=0;i<broj_dugmica;i++)     tmp[i] = Dugme[i]; delete[] Dugme; Dugme = tmp; // sa ovim dole inicijalizujemo dodati dugmic Dugme[broj_dugmica] = new C_dugme(...parametri...) broj_dugmica ++;

offline
  • Nom  Male
  • Građanin
  • Pridružio: 17 Nov 2004
  • Poruke: 168
  • Gde živiš: Shanghai, China

@Bone

Da bas tako - ono sto se alocira sa new[] se i brise sa delete[]

U primeru se inicijalizuju pointeri na pointere, i oni se inicijalizuju sa new[] i brisu sa delete[] dok se sam pointer inicijalizuje sa new bez [] i brise sa delete bez []

Procitaj pazljivije na koju temu je napisan primer. Problem nije alocirati / dealocirati vec DODATI ili ODUZETI iz vec alociranog niza novi objekat, bez kopiranja memorije, koristeci prednost pointera na pointere.

@Bone

Sad sam video update - da moze i tako Wink

offline
  • Pridružio: 18 Apr 2003
  • Poruke: 5001
  • Gde živiš: Beograd

mislio sam zbog ovoga:

"Obratite paznju da ako je ostalo samo jedno dugme tj. broj_dugmica == 1 pre brisanja, brisnje ide:

Kod:

delete Dugme[0]; Dugme[0] = NULL;
delete[] Dugme; Dugme = NULL;
broj_dugmica = 0;
"
ne shvatam zasto ide posebno "delete Dugme[0]; Dugme[0] = NULL; "

offline
  • Nom  Male
  • Građanin
  • Pridružio: 17 Nov 2004
  • Poruke: 168
  • Gde živiš: Shanghai, China

@Bone

Zato sto je Dugme[index] bilo nekad alocirano sa new C_dugme - bio je alociran pointer Dugme[0] - to je pointer a Dugme je pointer na njega.

Inace imas memory leak

Probaj - stavi u petlju da alocira sledece:

Dugme = new pC_dugme[1];
Dugme[0] = new C_dugme(...parametri...);
delete[] Dugme; Dugme = NULL;

sta bi sa drugim new???

evo probaj ovo:
for(int i=0;i<1000000000;i++) {     typedef char *pchar;     pchar *test = new pchar[1];     test[0] = new char;     delete[] test; test = NULL; }
u svakom pasu ces gubiti po jedan bajt memorije.


Dugme je niz od Dugme[0] Dugme[1] ....
Dugme[0] je objekat C_dugme

Sa Dugme = new pC_dugme[broj] smo inicijalizovali pointere
a objekti se inicijalizuju sa Dugme[0] = new C_dugme(...)

Dugme nije C_dugme vec pC_dugme.

offline
  • Pridružio: 18 Apr 2003
  • Poruke: 5001
  • Gde živiš: Beograd

eh pa tako da, ali ja nisam gore primetio kad si ti stavio pointer na pointer, i sad pokusavam da nadjem ali ne mogu da nadjem, mozda je previse kasno pa ne vidim nist ... Smile

offline
  • Nom  Male
  • Građanin
  • Pridružio: 17 Nov 2004
  • Poruke: 168
  • Gde živiš: Shanghai, China

@Bone

Sa ovim:
typedef C_dugme *pC_dugme;
sam definisao novi tip koji je pointer C_dugme.

Kasnije sam koristio ovo:
pC_dugme *Dugme; Dugme = new pC_dugme[broj_dugmica];

Mozda je trebalo da pC_dugme nazovem drugacije, da bi bila jasnija razlika izmedju pC_dugme i C_dugme - nadam se da ce ovo razjasniti "sta je pesnik hteo da kaze" Very Happy

Poz.

offline
  • Pridružio: 18 Apr 2003
  • Poruke: 5001
  • Gde živiš: Beograd

Nom ::@Bone

Sa ovim:
typedef C_dugme *pC_dugme;
sam definisao novi tip koji je pointer C_dugme.

e ovaj deo sam propustio Very Happy

sad mi je jasno, mada sam trebao da zakljucim po imenu promenljive Confused Smile

Ko je trenutno na forumu
 

Ukupno su 592 korisnika na forumu :: 2 registrovanih, 0 sakrivenih i 590 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 3466 - dana 01 Jun 2021 17:07

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: blue, kayvan6079