Member setzen mit call-by-reference



  • Hallo,

    in einem Projekt, das nicht von mir stammt habe ich folgende getter/setter Methoden gefunden:

    class SomeClass {
    private:
    	MemberType member;
    public:
    	void setMember(const MemberType& m) {
    		this->member = m;
    	}
    	const MemberType& getMember() {
    		return this->member;
    	}
    };
    

    wobei MemberType halt ne relativ große Klasse ist:

    class MemberType {
    private:
    	// ... viele member Variablen
    public:
    	// ... getter/setter
    	// ... anderes Zeug
    };
    

    Die Art und Weise, wie die Getter/Setter in SomeClass arbeiten wundert mich. Warum funktioniert diese Call-By-Reference Methode? Angenommen ich habe eine weitere Klasse AnotherClass , die selbst eine Membervariable vom Typ SomeClass besitzt und eine Methode, die deren member setzt:

    class AnotherClass {
    private:
    	SomeClass c;
    public:
    	void doSomething() {
    		MemberType m;
    		// ... setze Felder von m
    		c.setMember(m);
    	}
    };
    

    Nach meiner Vorstellung wird m doch bei Verlassen von doSomething() zerstört? Wie kann also die SomeClass::member einen gültigen Wert enthalten? Wird an irgendeiner Stelle doch eine Kopie vom ursprünglichen Objekt erstellt?

    Grüße,
    Björn



  • void setMember(const MemberType& m) {
            this->member = m; //da wird kopiert
        }
    


  • Ich verstehe nicht, wo das Problem sein soll. Kannst Du es detaillierter beschreiben, was Du glaubst, das hier passiert / eventuell schief geht?

    bhurling schrieb:

    Nach meiner Vorstellung wird m doch bei Verlassen von doSomething() zerstört? Wie kann also die SomeClass::member einen gültigen Wert enthalten?

    1. Ja
    2. Durch den Aufruf von setMember, nicht?

    bhurling schrieb:

    Wird an irgendeiner Stelle doch eine Kopie vom ursprünglichen Objekt erstellt?

    So in etwa. Was glaubst Du, was die Zuweisung in setMember macht?

    Ich habe den Eindruck, dass Du aus der Java-Welt kommst und Dich nur schwer daran gewöhnen kannst, dass Variablen von Klassentypen in C++ keine "Java-Referenzen" sondern die Objekte selbst sind.



  • Danke TyRoXx. Ich wollte nur verstehen, weshalb der Autor diese Art von Funktionsaufruf gewählt hat. Welchen Vorteil hat in diesem Fall call-by-reference, wenn innerhalb der Methode eben doch eine Kopie erzeugt wird?



  • bhurling schrieb:

    Danke TyRoXx. Ich wollte nur verstehen, weshalb der Autor diese Art von Funktionsaufruf gewählt hat. Welchen Vorteil hat in diesem Fall call-by-reference, wenn innerhalb der Methode eben doch eine Kopie erzeugt wird?

    Du musst nicht zwei Mal kopieren.

    void SomeClass::setMember(MemberType m) // <-- erste Kopie
    {
        member = m; // <-- zweite Kopie
    }
    

    Hier wird einer Membervariable ein Wert zugewiesen, diese Kopie ist also unvermeidlich. Allerdings hast du Recht, wenn es sich um lokale Kopien handelt, da kann man die Kopie auch in der Parameterliste durchführen (ist ggf. sogar von Vorteil bezüglich Optimierungen).

    void DoSomething(const AnyType& x)
    {
        AnyType copy = x;
        // arbeite mit copy
    }
    
    void DoSomething(AnyType x)
    {
        // arbeite mit x
    }
    

Anmelden zum Antworten