[ azzpoz @ 04.11.2013. 14:42 ] @
Code:
#include <iostream>
using namespace std;

class osoba
{
      char *ime;
      
      public:
             osoba()
             {
                    
                       ime = NULL;
             
             }
             osoba(char *i)
             {
                        ime = new char[strlen(i)+1];
                        strcpy(ime,i);
             }
             ~osoba()
             {       cout<<" Brisem: "<<ime<<endl;
                     delete []ime;
                     ime = NULL;
                     system("pause"); // kako bih vidio kada se poziva destruktor
             }
             void setIme(char *i);
             void predstaviSe();
};

void osoba::setIme(char *i)
{
     delete []ime;
     ime = NULL;
     
     ime = new char[strlen(i)+1];
     strcpy(ime,i);
}

void osoba::predstaviSe()
{
     cout<<"\n Ime: "<<ime<<" duzine: "<<strlen(ime)<<" size of("<<sizeof(ime)<<") "<<endl;
}

void promjena(osoba p)
{
     p.setIme("Security");
 
}

int main()
{

   osoba ja("Elite ");
      ja.predstaviSe();
   
   promjena(ja);

    
    ja.predstaviSe();
    
    cout<<"\n::::::: KRAJ ::::::"<<endl;
    system("pause>0"); return 0;}



Zašto se u funkciji promjena mora proslijediti objekat klase osoba kao referentni da bude "pravilnih" izmjena na objektu klase?

Objekat koji prosljeđujemo je kopija, ali njegovi atributi su u dinamičkom dijelu memoriju, pa zašto se ovo dešava, ne razumijem???
[ Burgos @ 04.11.2013. 15:02 ] @
Ako metodi promjena proslediš objekat po vrednosti, unutar te metode će se stvoriti kopija objekta, kao što si i rekao. Ta kopija objekta će imati pokazivač ime koji će da pokazuje na istu memorijsku lokaciju gde i originalni objekat (pokazivač će imati istu vrednost), međutim, ta dva pokazivača su fizički potpuno odvojena (iako sada pokazuju na isto mesto).

Pogledaj metodu setIme:

Code:

void osoba::setIme(char *i)
{
     delete []ime;
     ime = NULL;
     
     ime = new char[strlen(i)+1];
     strcpy(ime,i);
}


U ovoj metodi, pored velike greške usled nepostojanja konstruktora kopije (uništavaš memoriju na koju pokazuje i originalni objekat, pa on neće biti validan), ti postavljaš pokazivač u kopiji objekta na novu vrednost. Sada pokazivač ime u originalnom i u kopiranom objektu pokazuju na različite memorijske lokacije.



Citat:
Objekat koji prosljeđujemo je kopija, ali njegovi atributi su u dinamičkom dijelu memoriju, pa zašto se ovo dešava, ne razumijem???


Sva polja objekta ja se nalaze na steku. Pokazivač pokazuje na lokaciju na heap-u, ali se on nalazi na steku.
[ Mihajlo Cvetanović @ 04.11.2013. 15:42 ] @
Objekat ja u funkciji main i objekat p u funkciji promjena su dva različita objekta. Izmene nad p se odnose samo na p, a ja ostaje kakav je i bio. Ako parametar funkcije promjena promeniš u referencu na objekat onda p više nije potpuno drugi objekat (a i nije objekat nego referenca na objekat) nego je upravo ja, i zato bi se promene nad p odnosile upravo na ja.
[ Mihajlo Cvetanović @ 04.11.2013. 15:54 ] @
Postoji način da se reši ova gungula. Treba da zabraniš mogućnost kopiranja objekta, i onda ti kompajler ne bi dozvolio kod čiji bi rezultat bio kopiranje objekta. To se rešava uvođenjem privatnog copy konstruktora i operatora dodele.

Code:
class osoba
{
    // sve ostalo što već postoji

private:
    osoba(osoba const&);
    osoba operator=(osoba const&);
}


To je sve što je potrebno. Nije potrebno zaista definisati te dve funkcije, jer ih niko ne može pozvati, zato što su "private", a ako se slučajno desi da ih greškom pozoveš u kodu same klase osoba onda će ti linker reći da funkcije ne postoje, i tako te podsetiti da imaš grešku u kodu.
[ Burgos @ 04.11.2013. 16:24 ] @
Treba jednostavno proslediti referencu objekta, ako želiš da promeniš stanje objekta, a ne njegove kopije - nije potrebno zabranjivati kopiranje objekata u ovom slučaju (ali treba napisati ispravan konstruktor kopije i operator dodele!) i menjati klasu osoba, jer je u ovom slučaju problem u funkciji koja koristi istu.



[Ovu poruku je menjao Burgos dana 04.11.2013. u 17:47 GMT+1]