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ć