Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Referenca na objekt kao povratna vrijednost

[es] :: C/C++ programiranje :: C/C++ za početnike :: Referenca na objekt kao povratna vrijednost

[ Pregleda: 2308 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

virtualVoid

Član broj: 161084
Poruke: 698



+28 Profil

icon Referenca na objekt kao povratna vrijednost26.11.2007. u 15:17 - pre 198 meseci
Code:
Klasa& operatorXX(neki_parametri)...


Ako mi neko moze malo razjasniti sljedece: da li referencu na objekt kao povratnu vrijednost korisnimo SAMO kada zelimo da se NE kreira konstruktor kopije ili postoje i druge situacije? ovo sam susreo kod preklapanja operatora, ali vjerujem da cete mi moci dati neki opcenit savjet. Zasto uopce moramo koristiti referencu kao povratnu vrijednost? Npr. isto je koristimo kada preklapamo operator ostream objekta.
...
 
Odgovor na temu

xeron
Sarajevo

Član broj: 25909
Poruke: 133
89.146.167.*



Profil

icon Re: Referenca na objekt kao povratna vrijednost26.11.2007. u 15:40 - pre 198 meseci
Vozdra,
Na tvoje pitanje sam odgovorio u jednom postu o klasama općenito.
http://www.elitesecurity.org/t295677-0#1758040

Ovo je dio koji tebe zanima ;)

Code:

v1.Saberi(v2).PomnoziSkalarom(5).Ispisi();

nam nece dati zeljeni rezultat. Da bi rijesili ovaj problem metode trebaju da vracaju referencu na objekat, a ne kopije objekta sto je slucaj u gore navedenim metodama.

Code:

Vector &PomnoziSkalarom(double s){
    x= x*s; y= y*s; z= z*s;
    return *this;
}

Vector &Saberi(Vector &v){
    x= x+v.x; y= y+v.y; z= z+v.z;
    return *this;
 }


Ovako izmjenjene metode ce nam davati ocekivane rezultate, za razliku od onih koji su vracali kopiju objekta.

if (argc > 1 && strcmp(argv[1], "-advice") == 0) {
printf("Don't Panic!n");
exit(42);
}
 
Odgovor na temu

virtualVoid

Član broj: 161084
Poruke: 698



+28 Profil

icon Re: Referenca na objekt kao povratna vrijednost26.11.2007. u 17:02 - pre 198 meseci
Da li to znaci da nam referenca treba samo kod ulancavanja da bi se rezultat proslijedio pravom objektu, a ne njegovoj kopiji? Zbog toga onda referenca treba i kod indirekcije, te kod preklapanja operatora += i slicnih?

[Ovu poruku je menjao virtualVoid dana 26.11.2007. u 18:37 GMT+1]
...
 
Odgovor na temu

xeron
Sarajevo

Član broj: 25909
Poruke: 133
89.146.176.*



Profil

icon Re: Referenca na objekt kao povratna vrijednost26.11.2007. u 17:32 - pre 198 meseci
Razlog je bas to ulancavanje. Npr. uzmemo operator "<<" operator ispisa na izlazni tok. Kada bi povratni tip bio void ne bi imali mogućnost ulančavanja tipa
Code:
cout<<vect<<endl;

To se interpretira kao
Code:
(cout<<vect)<<endl
, uz preklopljeni operator kao:
Code:

operator <<(operator <<(cout,vect), endl)

Sto znaci da operatorska funkcija treba da vrati referencu na sam objekat izlaznog toka tj. da vrati sam taj objekat.
Sa referencom na objekat rjesavamo jos jedan problem, izbjegli smo kopiranje masivnog objekta tako sto smo stavili referencu na njega. Usteda brzine i memorije.
if (argc > 1 && strcmp(argv[1], "-advice") == 0) {
printf("Don't Panic!n");
exit(42);
}
 
Odgovor na temu

virtualVoid

Član broj: 161084
Poruke: 698



+28 Profil

icon Re: Referenca na objekt kao povratna vrijednost26.11.2007. u 17:43 - pre 198 meseci
Ok, to mi je sada mnogo jasnije. Stovise, tako slicno sam i ja mislio.

Drugo pitanje. Da li ovo sve znaci da npr. ako preklapam operator +, onda ne koristim referencu ako znam da ce se vrsiti samo sabiranje tipa

Code:
c=a+b;


Ali ako zelim koristiti

Code:
d=a+b+c;


Onda moram napraviti funkciju (funkcija je clanica u mom primjeru) sa referencom na originalni objekt

Code:
Klasa& operator+(const Klasa& obj);


Jesam li ovo dobro shvatio?

ps. povod mom pitanju je bio taj sto mi je jedan iskusniji kolega rekao da ne smijem pamtiti gdje idu reference, a gdje ne idu, jer kod preklapanja mozemo koristiti referencu u bilo kojoj situaciji (mislim kao povratnu vrijednost)
...
 
Odgovor na temu

Nemanja.Ciric
web dizajner/programer, Niteoweb
Novi Sad/Subotica

Član broj: 163398
Poruke: 63
*.ns.ac.yu.

Jabber: serj.cobain@gmail.com


Profil

icon Re: Referenca na objekt kao povratna vrijednost26.11.2007. u 18:57 - pre 198 meseci

Citat:
virtualVoid: Ok, to mi je sada mnogo jasnije. Stovise, tako slicno sam i ja mislio.

Drugo pitanje. Da li ovo sve znaci da npr. ako preklapam operator +, onda ne koristim referencu ako znam da ce se vrsiti samo sabiranje tipa

Code:
c=a+b;


Ali ako zelim koristiti

Code:
d=a+b+c;


Onda moram napraviti funkciju (funkcija je clanica u mom primjeru) sa referencom na originalni objekt

Code:
Klasa& operator+(const Klasa& obj);


Jesam li ovo dobro shvatio?

Mislim da nisi :).

Uzmimo primer klase Complex, klase kompleksnih brojeva koju si sam definisao tako da ima dva podatka člana koji su tipa double (jedan za realni, jedan za imaginarni deo). I ti naravno preklapaš operator +, da bi mogao da pišeš z=z1+z2 i dobiješ smislen rezultat.

Prvo i osnovno, pravilo je da se operatori koji ne menjaju objekte definišu kao prijateljske funkcije van same klase, a ne kao metode klase kao što si ti uradio sa
Code:
Klasa& operator+(const Klasa& obj);
.

Drugo, nikada nećeš vraćati rezultat sabiranja, niti bilo koje druge operacije ili funkcije koja NE MENJA TEKUĆI OBJEKAT po referenci! Zašto? Pa hajde da odradimo to hipotetičko sabiranje kompleksnih brojeva tako da vraća rezultat po referenci:

Code:

Complex& operator+(const Complex& arg1, const Complex& arg2){
  Complex temp;
  temp.real=arg1.real+arg2.real;
  temp.imag=arg1.imag+arg2.imag;
  return temp;
}


Šta smo vratili po referenci? Objekat temp. Šta je objekat temp - priveremena promenjiva funkcije +. Šta se dešava sa privremenim promenjivima kada izađu iz opsega, to jest kada se završi funkcija koja ih je stvorila? Bivaju uništeni. Upravo smo vratili referencu na nepostojeći objekat - KABOOOM! :). Dakle, kada funkcija menja tekući objekat onda rezultat vraćaš po referenci da ne bi objekat nad kojim vršiš radnju kopirao na steku, pa slao funkciji, pa onda rezultat opet stavljao na stek, pa to dodeljivao originalnom objektu, i još pride pozivao i destruktore.

Treće,
Code:
Klasa& operator+(const Klasa& obj);
ne možeš da realizuješ tako da sabira dva sabirka :). Možeš da ga realizuješ tako da na postojeći objekat doda onaj koji je u zagradi.

Četvrto,
Code:
d=a+b+c;
se izvršava na sledeći način: pošto se operandi operatora + grupišu sa leva na desno (po standardu, opet nisu svi kompajleri po standardu, te neki sabiraju sa desna na levo, što smo saznali na težak način, pripremajući se za elektrijadu xD) prvo će se sabrati a i b, rezultat koji je privremeni objekat, će se sabrati sa c, i rezultat tog sabiranja dodeliti objektu d. Čak i kada bi nekako vraćao rezultat po referenci (recimo, tako što bi napravio globalne promenjive, kojima bi lokalne funkcije dodeljivale vrednost, što je naravno KRAJNJE nepreporučivo, pa onda vraćao njihove reference) nije nikakav problem sabrati objekat i referencu, dva objekta ili dve reference, sve se to lepo fino odradi kako treba samo od sebe.


Citat:

ps. povod mom pitanju je bio taj sto mi je jedan iskusniji kolega rekao da ne smijem pamtiti gdje idu reference, a gdje ne idu, jer kod preklapanja mozemo koristiti referencu u bilo kojoj situaciji (mislim kao povratnu vrijednost) ;)

Kod preklapanja možeš operator plus preklopiti tako da realizuje adjungovanje matrice, ali to se ne radi. Vraćanje vrednosti preko referenca se kod preklapanja koristi samo kada i originalni C operator koji preklapaš to radi! (Pravilo o očuvanju semantike)
NĆirić
 
Odgovor na temu

[es] :: C/C++ programiranje :: C/C++ za početnike :: Referenca na objekt kao povratna vrijednost

[ Pregleda: 2308 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.