2D Array-Klasse Rückgabe einer Referenz bei Zuweisung



  • Ja hallo ich melde mich mal wieder. Diesmal geht es um eine Klasse, die ein dynamisches 2D Array erstellen soll. Sie soll dynamischen Speicher anfordern und auch wieder löschen. Meine Frage ist, warum die Funktion assign eine Referenz vom Typ der Klasse zurückgeben muss. Geht nicht auch einfach void ?

    #ifndef ARRAY2D_H
    #define ARRAY2D_H
    
    #include <iostream>
    #include <cassert>
    
    template<typename T>
    class Array2D {
    public:
    	Array2D(size_t z, size_t s)
    		: zeilen(z), spalten(s), ptr(new T[z*s]) {
    	}
    
    	Array2D(size_t z, size_t s, const T& wert)
    		: zeilen(z), spalten(s), ptr(new T[z*s]) {
    		init(wert);
    	}
    
    	Array2D(const Array2D<T>& a)
    		: zeilen(a.zeilen), spalten(a.spalten), ptr(new T[zeilen*spalten]) {
    		size_t anzahl = zeilen * spalten;
    		for(size_t i = 0; i < anzahl; ++i) {
    			ptr[i] = a.ptr[i];
    		}
    	}
    
    	~Array2D() {
    		delete [] ptr;
    	}
    
    	void swap(Array2D& a) {
    		size_t temp = zeilen;
    		zeilen = a.zeilen;
    		a.zeilen = temp;
    
    		temp = spalten;
    		spalten = a.spalten;
    		a.spalten = temp;
    
    		T* tempPtr = ptr;
    		ptr = a.ptr;
    		a.ptr = tempPtr;
    	}
    
    	Array2D& assign(Array2D a) {
    		swap(a);
    		return *this;
    	}
    
    	T& at(size_t z, size_t s) {
    		assert(z < zeilen && s < spalten);
    		return ptr[z * spalten + s];
    	}
    
    	const T& at(size_t z, size_t s) const {
    		assert(z < zeilen && s < spalten);
    		return ptr[z * spalten + s];
    	}
    
    	void init(const T& wert) {
    		size_t anzahl = zeilen * spalten;
    		for(size_t i = 0; i < anzahl; ++i) {
    			ptr[i] = wert;
    		}
    	}
    
    private:
    	size_t zeilen;
    	size_t spalten;
    	T *ptr;
    };
    
    #endif
    


  • Erstmal wundere ich mich wieso für Zuweisungen eine Memberfunktion und kein überladener Zuweisungs-Operator verantwortlich ist.

    RaggyGandalf schrieb:

    Meine Frage ist, warum die Funktion assign eine Referenz vom Typ der Klasse zurückgeben muss. Geht nicht auch einfach void ?

    Wieso "muss"? Gar nichts muss . Es ist nur in manchen Situationen nützlich, wenn die Zuweisungs-Funktion (nenne ich jetzt einfach mal so) eine Referenz auf das jeweilige Objekt zurückgibt.



  • Die Überladung kommt erst in späteren Kapiteln, weshalb dies hier noch verboten ist.

    Das heißt doch eigentlich, dass bei jedem Aufruf der Funktion die Referenz auch zurückgegeben wird oder? Entspricht das nicht auch einfach die Adresse der Instanz?



  • was ist das denn für ein buch ? erst werden klassen erklärt und später erst das überladen funktionen ? dieses konzept erschließt sich mir nicht so ganz.



  • vario-500 schrieb:

    was ist das denn für ein buch ? erst werden klassen erklärt und später erst das überladen funktionen ? dieses konzept erschließt sich mir nicht so ganz.

    Es geht um Operatorenüberladung. Da ist diese Reihenfolge schon korrekt :xmas1:



  • Edit: Hier stand Müll (s. u.)



  • Ich meine von *this



  • Ouh, ich war verwirrt, dachte das ist der andere Thread ⚠
    Sry!

    RaggyGandalf schrieb:

    Das heißt doch eigentlich, dass bei jedem Aufruf der Funktion die Referenz auch zurückgegeben wird oder? Entspricht das nicht auch einfach die Adresse der Instanz?

    Ich verstehe nicht so richtig, was du meinst.



  • Wenn ich eine Methode mit dem Rückgabetyp Array2D& <name>(parameter) habe, übergibt sie nicht einfach beim Aufruf die Adresse? In diesem Fall übergibt assign doch einfach die Adresse von this oder nicht?



  • RaggyGandalf schrieb:

    Wenn ich eine Methode mit dem Rückgabetyp Array2D& <name>(parameter) habe, übergibt sie nicht einfach beim Aufruf die Adresse? In diesem Fall übergibt assign doch einfach die Adresse von this oder nicht?

    Adresse von this wäre ja ein Array2D** ...
    Mit Adressen hat das erstmal nix zu tun, es sei denn, Du willst Dich über die Implementierung des Standards in Deinem Compiler unterhalten...

    Naja und warum eine Referenz zurückgegeben wird?
    Damit du schreiben kannst

    Array2D a,b,c;
    a.assign(b.assign(c));
    

    bzw. später, wenn Du aus assign() wirklich den Zuweisungsoperator operator=() machst:

    Array2D a,b,c;
    a = b = c; // == a.operator=(b.operator=(c))
    

    Natürlich musst Du keine Referenz retournieren, ist aber allgemeine Praxis.



  • Okay, das wurde so direkt nicht im Buch beschrieben. Ich hab es jetzt jedenfalls ausprobiert und verstanden. Danke :xmas1:



  • Hallo,
    ich bin bei www.github.com/decimad/na_containers auch gerade dabei, eine array2d-Klasse zu implementieren. Vielleicht sollten wir kollaborieren? 🙂

    Grüße,
    Deci :xmas1:


Anmelden zum Antworten