einfache Matrizenklasse, Vererbung



  • Hübsche Beispiele, die alle das selbe Ergebnis haben.

    Der Doppelvektor ist doch nur deshalb irritierend, weil ich ihn in der obigen Array-Klasse als Grundlage genommen habe. Aber das ist doch hinfällig. Gibt es nicht mehr.

    Edit: Verstehe aber, was Ihr meint. Wenn die Klasse umgeschrieben ist, sollte man analog zur Struktur auch nur einen Vektor übergeben können. Finde es aber nicht tragisch, trotzdem auch einen Doppelvektor anzunehmen.



  • @titan99_ sagte in einfache Matrizenklasse, Vererbung:

    std::copy(f0.begin(), f0.end(), vArray.end())
    

    wth?


  • Gesperrt

    @Swordfish Sorry, dachte es geht so, den std::back_inserter braucht es anscheinend.

    std::copy(f0.begin(), f0.end(), std::back_inserter(vArray))
    
    

    Ideone



  • Bei Übergabe eines Vektor muss ich noch die Dimensionen angeben, also Mat mt(3, 4, vec);. Das entfällt auch bei einem Doppelvektor. Wie gesagt, als Eingabe, nicht als Struktur.



  • Die neue Array-Klasse ist jetzt soweit fertig, waren nur einige Inhalte der .cpp auszutauschen. Ich weiß, Ihr schreibt sowas in drei Minuten 😉

    using floatVec = std::vector<float>;
    using floatArray = std::vector<std::vector<float>>;
    //Ja, die dummen Namen sind noch da :roll_eyes:
    
    class Matrix
    {
    protected:
    	Matrix() {}
    	~Matrix() {}
    	Matrix(const Matrix& mx) {}
    	Matrix operator=(const Matrix& mx) { copyMatrix(mx); }
    
    	Matrix(const std::size_t rows, const std::size_t columns);
    	Matrix(const std::size_t rows, const std::size_t columns, const float v);
    	Matrix(const std::size_t rows, const std::size_t columns, const floatVec& vec);
    	Matrix(const floatArray& array);
    	
    public:
    	float element(const std::size_t row, const std::size_t column) const;
    	floatVec elements() const;
    	std::size_t rows() const;
    	std::size_t columns() const;
    	std::size_t size() const;
    	floatVec row(const std::size_t r) const;
    	floatVec column(const std::size_t c) const;
    
    	void printElement(const std::size_t row, const std::size_t column, std::ostream& stream = std::cout) const;
    	void printRow(const std::size_t row, std::ostream& stream = std::cout) const;
    	void printColumn(const std::size_t column, std::ostream& stream = std::cout) const;
    	void print(const std::string& note = {}, std::ostream& stream = std::cout) const;
    	
    protected:
    	void fillMatrix(const float v); //könte wegfallen, wird aber in der Testphase noch benötigt
    	void fillMatrix(const floatVec& vec);
    	void fillMatrix(const floatArray& array);
    	void setElement(const std::size_t row, const std::size_t column, const float v);
    	void copyMatrix(const Matrix& mx);
    	
    	bool operator == (const float v) const;
    	bool operator != (const float v) const;
    	bool sameDimension(const Matrix& mx) const;
    	bool operator == (const Matrix& mx) const;
    	bool operator != (const Matrix& mx) const;
    
    private:
    	std::size_t rows_ = 0;
    	std::size_t columns_ = 0;
    	floatVec elements_;
    	float val_ = 0.;
    
    	void resizeElements(const float v);
    	floatArray toArray(const floatVec& vec) const; 
    	/*ist noch drin, weil ich die Funktion einen DoppelVector!=(rows * columns) aufnehmen zu können,
    	für einzelne Vektoren nicht ändern wollte*/
    };
    
    

  • Mod

    Wieso verletzt du die Rule of zero? Was denkst du, wieso du protected-Attribute brauchst? Was passiert bei einem Vergleich einer Matrix mit einem Skalar?



  • Weil ich mich an die Rule of Three halten wollte.
    Weil ich die Funktionen public machen wollte, aber nicht private machen konnte.

    Nicht eingebaut, wußte gar nicht, das man das brauchen könnte. Wie gesagt, ist ne einfache Klasse.


  • Mod

    @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Weil ich mich an die Rule of Three halten wollte.

    Aber wieso? Du verwaltest keine Ressourcen, was so auch richtig ist. Hingegen sind deine 3 falsch implementiert.

    Weil ich die Funktionen public machen wollte, aber nicht private machen konnte.

    Also mach sie public?

    Nicht eingebaut, wußte gar nicht, das man das brauchen könnte. Wie gesagt, ist ne einfache Klasse.

    Na, du sagst in Zeile 39/40, dass deine Klasse das könnte. Ich wundere mich hingegen, was das sein soll, weil das nicht sinnvoll klingt. Also lügt deine Zeile 39/40?

    PS: Wozu ist der Member val_ da?



  • @SeppJ sagte in einfache Matrizenklasse, Vererbung:

    Aber wieso? Du verwaltest keine Ressourcen, was so auch richtig ist. Hingegen sind deine 3 falsch implementiert.

    Wie würde man das richtig machen? Und ich brauche keinen Destruktor und Kopier-Konstruktor?

    @SeppJ sagte in einfache Matrizenklasse, Vererbung:

    Also mach sie public?

    Dann passiert das, was Bashar mit diag.resizeMatrix(3, 4);meinte. Auch wenn die jetzt weg ist.
    Edit: Hatte mich verschrieben, meinte nicht public machen wollte.

    @SeppJ sagte in einfache Matrizenklasse, Vererbung:

    Na, du sagst in Zeile 39/40, dass deine Klasse das könnte. Ich wundere mich hingegen, was das sein soll, weil das nicht sinnvoll klingt. Also lügt deine Zeile 39/40?

    Da sollen eigentlich floats auf Gleicheit geprüft werden. Aber ich müsste natürlich noch den Ort des float angeben. Danke.

    @SeppJ sagte in einfache Matrizenklasse, Vererbung:

    PS: Wozu ist der Member val_ da?

    Ist der Wert mit dem standardmäßig eine Matrix gefüllt werden kann oder soll.



  • @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Wie würde man das richtig machen? Und ich brauche keinen Destruktor und Kopier-Konstruktor?

    Rule of Zero

    @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Da sollen eigentlich floats auf Gleicheit geprüft werden. Aber ich müsste natürlich noch den Ort des float angeben. Danke.

    Versteh' ich nicht.

    @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Ist der Wert mit dem standardmäßig eine Matrix gefüllt werden kann oder soll.

    Einfach mit float{} initialisieren?



  • @Swordfish sagte in einfache Matrizenklasse, Vererbung:

    @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Da sollen eigentlich floats auf Gleicheit geprüft werden. Aber ich müsste natürlich noch den Ort des float angeben. Danke.

    Versteh' ich nicht.

    Ich jetzt auch nicht mehr 🙂 Eigentlich sollte in der Funktion nur alle Werte der Matrix mit einer anderen verglichen werden. Habe ich wohl verbockt. Bis auf sameDimension() sind die dortigen Vergleichsoperatoren noch gar nicht implementiert.

    Ist natürlich blöd, unfertige Funktionen zu zeigen, aber so hätte ich gar nicht gewusst, was noch alles an der Klasse nicht richtig stimmt.

    @Swordfish sagte in einfache Matrizenklasse, Vererbung:

    Einfach mit float{} initialisieren?

    die val_kommt ganz raus, ist überflüssig wie das size_ganz oben. Wenn ein bestimmter Wert rein soll, passiert das über den Konstruktor. Außer das ist auch nicht in Ordnung.



  • @zeropage

    Hast du die Klasse mal ausprobiert? Wie erstellst du denn eine Instanz mit den protected Konstruktoren?



  • @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Eigentlich sollte in der Funktion nur alle Werte der Matrix mit einer anderen verglichen werden.

    Das klingt mehr nach find() oder component_exists() oder sowas.

    @zeropage sagte in einfache Matrizenklasse, Vererbung:

    die val_ kommt ganz raus, ist überflüssig wie das size_ ganz oben.

    Unbedingt merken musst Du Dir nur width (columns), size merkt sich der vector.



  • @Jockelx sagte in einfache Matrizenklasse, Vererbung:

    @zeropage

    Hast du die Klasse mal ausprobiert? Wie erstellst du denn eine Instanz mit den protected Konstruktoren?

    Die werden hier aufgerufen

    class Mat : public Matrix
    {
    public:
    	Mat() {}
    	~Mat() {}
    	Mat(const Matrix& mt) : Matrix(mt) {}
    	Mat operator=(const Matrix& mt) { copyMatrix(mt); }
                                
    	Mat(const std::size_t rows, const std::size_t columns) :                      Matrix(rows, columns) {}
    	Mat(const std::size_t rows, const std::size_t columns, const float v) :       Matrix(rows, columns, v) {}
    	Mat(const std::size_t rows, const std::size_t columns, const floatVec& vec) : Matrix(rows, columns, vec) {}
    	Mat(const floatArray& fArray) :                                               Matrix(fArray) {}
    
    protected:
    
    	/*void operator+=(const float f);
    	void operator-=(const float f);
    	void operator*=(const float f);
    	void operator/=(const float f);
    	void operator+=(const Mat& mt);
    	void operator-=(const Mat& mt);
    	Mat operator+(const float f) const;
    	Mat operator-(const float f) const;
    	Mat operator*(const float f) const;
    	Mat operator/(const float f) const;
    	Mat operator+(const Mat& mt) const;
    	Mat operator-(const Mat& mt) const;
    	Mat operator*(const Mat& mt) const;*/
    };
    
    class DMat : public Mat
    {
    public:
    	DMat() {}
    	~DMat() {}
    	DMat(const Mat& mt) : Mat(mt) {}
    	DMat operator=(const Mat& mt) {}
    
    	DMat(const std::size_t size) :                 Mat(size, size), unitSize_(size) { constructD(); }
    	DMat(const std::size_t size, const float dv) : Mat(size, size), unitSize_(size), dv_(dv) { constructD(); }
    
    	void setDv(const float v) 
    	{ 
    		dv_ = v;
    		constructD();
    	}
    	float dv() const { return dv_; }
    	std::size_t uSize() const { return unitSize_; }
    
    private:
    	std::size_t unitSize_ = 0;
    	float dv_ = 1.;
    
    	void constructD()
    	{
    		for (std::size_t n = 0; n < unitSize_; ++n) {
    			setElement(n, n, dv_);
    		}
    	}
    };
    
    class RVec : public Mat
    {
    public:
    	RVec() {}
    	~RVec() {}
    	RVec(const Mat& rv) : Mat(rv) {}
    	RVec operator=(const Mat& rv) {}
    
    	RVec(const std::size_t size) :                      Mat(1, size), size_(size) { }
    	RVec(std::initializer_list<float> list) :           Mat(1, list.size(), list), size_(list.size()) {}
    	RVec(const floatVec& vec) :                         Mat(1, vec.size(), vec), size_(vec.size()) {}
    	RVec(const std::size_t size, const floatVec& vec) : Mat(1, size, vec), size_(size) {}
    
    private:
    	std::size_t size_ = 0; //noch testweise drin
    };
    
    /*class CVec : public Mat
    {
    public:
    	CVec() {}
    	~CVec() {}
    	CVec(const Mat& cv) : Mat(cv) {}
    	CVec operator=(const Mat& cv) {}
    
    	CVec(const std::size_t size) :                      Mat(size, 1), size_(size) { }
    	CVec(std::initializer_list<float> list) :           Mat(list.size(), 1, list), size_(list.size()) {}
    	CVec(const floatVec& vec) :                         Mat(vec.size(), 1, vec), size_(vec.size()) {}
    	CVec(const std::size_t size, const floatVec& vec) : Mat(size, 1, vec), size_(size) {}
    
    private:
    	std::size_t size_ = 0; //noch testweise drin
    };*/
    
    


  • @Swordfish sagte in einfache Matrizenklasse, Vererbung:

    Das klingt mehr nach find() oder component_exists() oder sowas.

    Ja, danke für die Bezeichner. Ich hatte ohne Implementierung noch nicht richtig darüber nachgedacht, deshalb ist das bei rausgekommen.



  • @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Die werden hier aufgerufen

    Ah, okay, das ist eine Basisklasse. Ob das jetzt sinnig ist, sei dahin gestellt, aber mach mal den Destruktor virtual, sonst sieht die Klasse so aus, als ob sie nicht so gerne möchte, dass von ihr abgeleitet wird.



  • Doppelpost



  • Ok, danke. Dachte, das wäre nur bei virtuellen Funktionen notwendig. Ist noch was mit den Standard-Konstruktoren nicht richtig?

    @Jockelx sagte in einfache Matrizenklasse, Vererbung:

    Ah, okay, das ist eine Basisklasse. Ob das jetzt sinnig ist, sei dahin gestellt,

    Wäre es besser darauf zu verzichten und die Matrix-Operatoren auch in die Matrix-Klasse statt in die Mat zu packen?



  • @zeropage
    Ja, und nein. Die Operatoren solltet du nach Möglichkeit als freie Funktionen implementieren.



  • Richtig, hatte ich auch vor, deshalb sind sie noch auskommentiert. Sie arbeiten aber korrekt. Nur mit der Vererbung habe ich Probleme. Zu dem Thema hatte auch Finnegan gestern was geschrieben.


Anmelden zum Antworten