[Erledigt] Finde den Fehler nicht



  • drakon schrieb:

    Man merkt, dass du ein wenig auf der Leitung stehst.. 😉

    Wird Zeit gleich Feierabend zu machen.
    Gibt es generell etwas am Klassen-Design zu verbessern?



  • Ohne zu wissen, was die Klassen genau machen sollen ist das eher schwer.
    Aber das mit dem zurückgeben von nicht konstanten Referenzen habe ich ja bereits angesprochen.

    btw:
    Deutschland spielt und du bist am arbeiten? 😛



  • drakon schrieb:

    btw:
    Deutschland spielt und du bist am arbeiten? 😛

    Die verlieren eh 3:0
    * duck und weg *



  • Es ist so:

    Kurz:
    Ich habe Koordinaten mit einer bestimmten
    Dimension(im Beispiel Dimension=3) in
    verschiedenen Koordinatensystemen
    (im Beispiel Anzahl der Koordinatensysteme=3).

    Diese sollen möglichst bequem abgerufen und gespeichert werden können.

    Lang:
    Ich habe ein Panoramabild welches auf eine Kugel
    projeziert wird und klicke darin mit der Maus.

    Bekomme XY Bild-Koordinaten der Maus -> Transformiere sie
    in Kugelkoordinaten und speichere sie ab.

    Das Zusammengeklickte (Punkte/Knoten/Maschen) soll
    eine Topologie darstellen.

    Die Klasse Topoobject speichert die gemeinsamen
    Eigenschaften wie die Objekte gezeichnet werden sollen.

    Coord ist die klassische Koordinate. Sie gehört immer
    irgend einem Koordinatensystem an.

    Knot ist die Knotenklasse die eine beliebige
    Anzahl von Koordinaten speichert.

    Zwei Knoten sind eine Ecke usw..

    Die ganze Klassenhierarchie sieht so aus:

    #include <vector>
    #include <cstdarg>
    
    #include "assert.h"
    #include "panoconstants.h"
    #include "geotopology.h"
    
    #ifndef TOPOOBJECT_H
    #define TOPOOBJECT_H
    
    typedef unsigned int puint;
    
    // Limits
    typedef struct{puint max_color,max_size,max_code,max_comment;} topolimits;
    topolimits const defaultlimits = {16777216,100,1000,10000};
    
    // Formats
    typedef struct{puint HVD,XYZ;} pcoordformats;
    pcoordformats const coordformats = {0,1};
    
    // Colors
    typedef struct {puint color,size,code;std::string comment;} topoproperty;
    
    class Topoobject{
    
    	private:
    
    		puint color;
    		puint size;
    		puint code;
    		std::string  comment;
    
    	public:
    
    		static const topoproperty propdefault;
    		static const topoproperty propcoord;
    		static const topoproperty propknot;
    		static const topoproperty propedge;
    		static const topoproperty propface;
    
    		Topoobject();
    		Topoobject(topoproperty new_property);
    		Topoobject(puint color, puint size, puint code,const std::string &comment);
    
    		void set_size(puint new_size);
    		void set_color(puint new_color);
    		void set_code(puint new_code);
    		void set_comment(const std::string &new_comment);
    
    		puint get_code() const;
    		puint get_size() const;
    		puint get_color() const;
    		std::string const &get_comment() const;
    
    };
    
    class Coord : public Topoobject{
    
    	private:
    
    		std::vector<double> elements;
    		puint format;
    
    	public:
    		Coord();
    		Coord(puint format, puint maxdim, ... );
    		Coord(puint format,puint color,puint size,puint code,const std::string &comment, puint maxdim, ... );
    
    		void set_dim(puint dim, double new_element);
    		void set_xyz(double x,double y, double z);
    		void set_hvd(double h, double v, double d);
    		void set_format(puint new_format) const;
    
    		puint get_format() const;
    		double get_dim(puint dim) const;
    
    };
    
    class Knot : public Topoobject{
    
    private:
    
    	std::vector<Coord> coordinatesystem;
    
    public:
    
    	Knot();
    	Knot(puint maxsys ... );
    
    	double get_distance(puint sys, Knot &new_knot) const;
    	Coord get_sys(puint format) const;
    	Coord &set_sys(puint sys);
    	void set_sys(Coord new_coord,puint format);
    
    };
    
    class Edge : public Topoobject{
    
    	private:
    
    		puint startknot_id,endknot_id,left_area,right_area;
    
    	public:
    		Edge(puint startknot_id, puint endknot_id);
    		void set_startknot_id(puint new_startknot_id);
    		void set_endknot_id(puint new_endknot_id);
    
    		puint get_startknot_id() const;
    		puint get_endknot_id() const;
    
    };
    
    class Face : public Topoobject{ };
    
    #endif
    


  • darkfate schrieb:

    l'abra d'or schrieb:

    darkfate schrieb:

    Könntest du mir jetzt bitte erklären warum die getter uns setter da unsinning sein sollten?

    Die getter sind nicht das Problem. Und ein setter setzt normalerweise was, oder? Dein setter ist aber nur ein non-const-ref-getter...

    Wie macht man es besser?

    Ich möchte die Variable nicht public freigeben.

    Bin nicht der Profi, aber statt einer Methoden-Verkettung und den direkten Zugriff auf eine Methode von Klasse B, würde ich vorschlagen zusätzliche Methoden
    in Klasse A einfügen:

    void set_dimval(int pos,int dim, double val) {sys[pos].set_dim(dim,val);}
    double get_dimval(int pos, int dim)const {return sys[pos].get_dim(dim);}
    
    //Nutzung, finde ich intuitiver
    classa.set_dimval(i,j,1.0);
    classa.get_dimval(i,j);
    

    Hat aus meiner Sicht auch den Vorteil, dass der Benutzer von A sich nur mit dem Interface von A auseinandersetzen muss.



  • einwurf schrieb:

    ...

    Guter Einwand. Dann hätte ich aber vier statt zwei Funktionen..



  • darkfate schrieb:

    Guter Einwand. Dann hätte ich aber vier statt zwei Funktionen..

    Sofern dadurch die Schnittstelle leichter zu bedienen (da Verständlicher) ist, ist dies das kleinste Übel.



  • asc schrieb:

    darkfate schrieb:

    Guter Einwand. Dann hätte ich aber vier statt zwei Funktionen..

    Sofern dadurch die Schnittstelle leichter zu bedienen (da Verständlicher) ist, ist dies das kleinste Übel.

    startknot.get_sys(sys).get_dim(i) = 123.123;
    // oder
    classa.set_dimval(i,j,1.0) = 123.123;
    

    Ich weiß nicht was hier intuitiver ist..



  • darkfate schrieb:

    Ich weiß nicht was hier intuitiver ist..

    Gar keines, weil es unsinnig ist, eine Funktion "setter" zu nennen, die aber nur eine non-const-Referenz zurückgibt, der man dann den Wert doch wieder manuell zuweisen muss - da kannst du gleich mit "alles-public-structs" arbeiten und auf Funktionen verzichten (ganz hart formuliert).
    Ersteres ist einfach unübersichtlich und für den Anwender schwer nachzuvollziehen, weil er in zwei Dokus nachschauen muss, um auf das korrekte Setzen zu kommen.

    Schau auch mal in andere Frameworks - z.B. Qt mit dem QTableWidget - wenn es an Zugriffe auf Items in mehrdimensionalen Objekten geht, kapselt das eigentlich immer die verwaltende Klasse in _einen_ Funktionsaufruf (z.B. QTableWidget::setItem( int row, int column, QTableWidgetItem* item)).
    Vor allem kannst du dadurch komplett auf die Preisgabe der inneren Struktur verzichten! Der Benutzer braucht nur "A" mit sienen Funktionen kennen, und nicht auch noch "B" welches durch irgendeine Funktion von "A" geholt werden muss...



  • franz schrieb:

    ...

    Hmm irgendwie hast du schon recht. Danke für den Tipp mit Qt, ich werde mich danach richten.

    Danke auch an alle Antwortenden.


Anmelden zum Antworten