tiefe Kopie -> wie funktioniert das genau?



  • hier wird eine Tiefe Kopie erstellt..

    #include <iostream.h>
    
    class Cat
    {
    public:
    	Cat();
    	Cat (Cat &);
    	~Cat();
    
    	int GetAge() const {return *itsAge;}
    	int GetWeight() const {return *itsWeight;}
    	void SetAge(int age) {*itsAge = age;}
    
    private:
    	int *itsAge;
    	int *itsWeight;
    };
    
    Cat::Cat()
    {
    	itsAge = new int;
    	itsWeight = new int;
    
    	*itsAge = 5;
    	*itsWeight = 9;
    }
    
    Cat::Cat(Cat & rhs)
    {
    	itsAge = new int;
    	itsWeight = new int;
    	*itsAge = rhs.GetAge();
    	*itsWeight = *(rhs.itsWeight); 
    }
    
    Cat::~Cat()
    {
    	delete itsAge;
    	itsAge = 0;
    	delete itsWeight;
    	itsWeight = 0;
    }
    
    int main()
    {
    	Cat Frisky;;
    	cout << "Alter von Frisky: " << Frisky.GetAge() << endl;
    	cout << "Alter von Frisky auf 6 setzen.. \n";
    	Frisky.SetAge(6);
    
    	cout << "Boots auf Frisky erzeugen\n";
    	Cat Boots(Frisky);
    	cout << "Alter von Frisky: " << Frisky.GetAge() << endl;
    	cout << "Alter von Boots : " << Boots.GetAge() << endl;
    	cout << "Alter von Frisky auf 7 setzen...\n";
    
    	Frisky.SetAge(7);
    	cout << "Alter von Frisky " << Frisky.GetAge() << endl;
    	cout << "Alter von Boots " << Boots.GetAge() << endl;
    	return 0;
    }
    

    vor allem der Kopierkonstruktor und das bissle Code macht mir Probleme
    der Sinn und Zweck ist mir Klar.. nur nicht wie man das genau macht

    Cat::Cat(Cat & rhs)
    {
    	itsAge = new int;
    	itsWeight = new int;
    	*itsAge = rhs.GetAge();
    	*itsWeight = *(rhs.itsWeight); 
    }
    

    hoffe ihr könnt mir etwas weiter helfen

    MFG Insane



  • insane_desire schrieb:

    hvor allem der Kopierkonstruktor und das bissle Code macht mir Probleme
    der Sinn und Zweck ist mir Klar.. nur nicht wie man das genau macht

    Was ist denn genau unklar?



  • jupp.. hätte mich genauer ausdrücke sollen

    Cat::Cat(Cat & rhs)
    {
        itsAge = new int;
        itsWeight = new int;
        *itsAge = rhs.GetAge();
        *itsWeight = *(rhs.itsWeight); 
    }
    

    zu dem bissle Code:

    Wann wird dieser Code durchlaufen? wenn das neue Objekt schon exestiert?
    und in welchem Objekt läuft es ab (Original oder Kopie)?
    und was ist rhs ist es das Originale Objekt oder wieder eine Kopie?

    mir sind die Abläufe nicht so ganz klar..

    ein Beispiel:
    Objekt wird erstellt > ein Wert wird zugewiesen > eine Kopie des Objektes wird erstellt > Kopierkonstruktor macht eine Kopie und weißt itsAge und itsWeight von dem Originalen Objekt an die Zeiger von der Kopie die schon neuen Speicherplatz reserviert haben >> (Zwischenfrage: was passiert mit rhs? >> dann müsste der Destruktor ja zweimal laufen.. einmal für das Originale Objekt und das andere mal für rhs??) oder ist rhs die Kopie die ich erstellt habe also boots??

    du sieht.. ich bin etwas verwirrt..

    Gruß Insane



  • was du meinst ist der copyconstructor.
    in einem normalen constructor gibst duw erte an, in einem copy constructor wird das objekt mit einem anderen objekt des selben typs initialisiert.
    bsp:

    class test{
        private:
            int a;
            int b;
        public:
        test(int _a,int _b){
            a=_a;
            b=_b;    
        }
        test(test& objekt){
             a=objekt.a;
             b=objekt.b;
        }
        void display(){
             cout<<a<<" "<<b<<endl;
        }    
    };
    //in der main funktion
    test test1(10,12);
    test test2(2,3);
    test1.display();//gibt 10 12 aus
    test2.display();//gibt 2 3 aus
    test test3(test1);//<-copyconstructor
    test3.display();//gibt 10 12 aus
    

    bei einem normalen kopieren werden alle daten so wie sie sind übertragen.
    bei pointern macht dies aber keinen sinn, da man ja die werte auf die die pointer zeigen haben will(aufjedenfall normalerweise) und nicht die position auf die die pointer zeigen.

    erklärung:

    int* a=5;
    int* b;
    //nun will man b den gleichen wert geben wie ihn a hat, ohne die eigenständigkeit von a zu verlieren
    *b=*a;
    *a=6;
    //wenn man nun *a ausgibt erhält man 6 und bei *b 5
    b=a;
    *a=6;
    //ausgabe nun bei beiden 6
    


  • @ otze
    das hab ich schon verstanden
    eine tiefe Kopie muss gemacht werden, wenn der Speicher auf dem Heap reserviert wird, da ansonsten die Kopie (wenn das Original seinen Gültigkeitsbereich verliert) ins leere zeigen könnte

    int* a= new int;
    *a = 5
    int* b = new int;
    
    *b=*a;
    *a=6;
    
    b=a;
    *a=6;
    

    ich verstehe den ablauf einer Kopie nicht
    das Original Objekt exestiert.. ich komme zur folgenden Zeile

    Cat Boots(Frisky);
    

    was passiert dann?? wird der Konstrukor(der Kopie) oder der Kopierkonstrukor (des Originals) aufgerufen.. da man ja neue Zeiger erstellen muss (itsAge und itsWeight)

    und wann wird dieser Teil der Kopie durchlaufen?

    public:
        Cat();
        Cat (Cat &);
        ~Cat();
    
        int GetAge() const {return *itsAge;}
        int GetWeight() const {return *itsWeight;}
        void SetAge(int age) {*itsAge = age;}
    
    private:
        int *itsAge;
        int *itsWeight;
    

    müsst ja vor dem aufruf des Kopierkonstruktor passieren



  • konstruktoren werden immer nur vom neuen objekt aufgerufen, es wird konstruiert.
    in dem fall wird der copier contsurctor aufgerufen, anstatt des normalen constructors.

    oder anders ausgedrückt:

    foo(x) ruft immer foo(), und nicht x.foo() auf

    //edit
    dein copyconstructor tut das:
    itsAge = new int;
    itsWeight = new int;
    *itsAge = rhs.GetAge();
    *itsWeight = *(rhs.itsWeight);

    ganz vereinfacht ausgedrückt(und auch nicht syntaktisch richtig ;)) tut dein compiler das:

    //pseudocode
    //Cat Boots(Frisky);
    Boots.itsAge=new int;
    Boots.itsWeight=new int;
    *Boots.itsAge=*Frisky.itsAge;
    *Boots.itsWeight=*Frisky.itsWeight;
    


  • @otze

    geht doch.. habs jetzt endlich geschnallt
    man muss es mir nur lang genug erklären 😉
    thx


Anmelden zum Antworten