Methoden einer anderen Klasse benutzen



  • Hallo,

    obwohl die Frage eher trivial erscheint, ist es doch ein ganzer Fragenkomplex, den ich ohne Code leider nicht darstellen kann.

    Ich habe folgende Klasse

    struct AffineProperties
    {
        double mov_length = 1.0;
        int mov_phi = 0;
        double scale_x = 1.0;
        double scale_y = 1.0;
        int rot_phi = 0;
    
        double a = 1.0;
        double b = 0;
        double c = 0;
        double d = 1.0;
        double e = 0;
        double f = 0;
    
        void print() const;
        void reset();
    };
    
    class AffineGraphic
    {
    public:
    
        template<typename GraphObject> AffineGraphic( const GraphObject& obj ) :
            graphobject_name( obj.name ),
            side_length( obj.side_length ),
            points( obj.points ),
            edges( obj.edges )
        {
            cpoints.resize( points.size() );
            calculateObject();
        }
    
        AffineGraphic() {} //um ein Objekt in Shape zu erstellen
    
        const std::string& name() const;
        void print() const;
    
        void scaleMove( double x, double y );
        void move( double length, int phi );
        void rotate( int phi );
        void reset();
        void draw( const DrawArea& draw,
                   const Char& chr,
                   int char_mix_mode = BACKGROUND,
                   bool show = false );
    
    private:
    
        Point point;
        Edge edge;
        CharPoint cpoint;
    
        std::string graphobject_name;
        double side_length = 0;
        std::vector<Point> points;
        std::vector<Edge> edges;
        std::vector<CharPoint> cpoints;
    
        AffineProperties base_p, p;
        const int zfactor = 200;
    
        void calculateObject();
        void mapObject();
    };
    

    und folgende in Entwicklung

    class Shape
    {
    public:
    
        static Shape peek( int x, int y, int width, int height );
        static Shape load( const std::string& name );
    
        const std::string& name() const;
        std::size_t size() const;
        int width() const;
        int height() const;
     
        void print() const;
        void move( double length, int phi );
    
        void poke( const DrawArea& draw,
                   int x, int y,
                   int char_mix_mode = NONE ) const;
    
        void save( const std::string& name );
    
    
    private:
    
        AffineGraphic affine;
        Point point;
        CharPoint cpoint;
        std::vector<Point> points;
        std::vector<CharPoint> cpoints;
    
        std::string shape_name;
        int shape_width  = 0;
        int shape_height = 0;
    
        void toPoints();
        void calculateShape();
        void mapShape();
    };
    

    Nun möchte ich einige Methoden aus der ersten in der zweiten Klasse benutzen

    void Shape::print() const
    {
        //affine.points = points;
        affine.print();
    }
    
    void Shape::move( const double length, const int phi )
    {
        affine.move( length, phi );
    }
    

    Wie bringe ich die points aus AffineGraphic dazu die points aus Shape zu nehmen, und dazu obwohl sie private sind?


  • Global Moderator |  Mod

    Wenn du möchtest, dass jemand an deinen privaten Teilen rumspielen darf, dann musst du ihm halt entsprechend Zugriff genehmigen. Entweder, indem du jedem Zugriff gibst, oder indem du ausgewählten Freunden Zugriff gewährst.

    Deine Klassen sehen arg wirr aus. Ich kann mir durch angucken nicht erschließen, was du dir dabei gedacht hast, und das ist ein ganz schlechtes Zeichen für das Design. Das gilt ganz besonders für die diversen Datenmember deiner Klassen.



  • Ohje, ist es immer noch so schlimm? Ich dachte, ich hätte mich inzwischen weiter entwickelt.

    Was erschließt sich zB beim ersten Durchsehen nicht?



  • @lemon03 sagte in Methoden einer anderen Klasse benutzen:

    Point point;
    Edge edge;
    CharPoint cpoint;
    

    Was sollen diese drei Einzelmember bewirken, wo du doch schon Vektoren davon speicherst?
    Und bist du dir über die Bedeutung des Members const int zfactor = 200; im Klaren?



  • Also wegen den Strukturen und Vektoren davon müsste ich jetzt tatsächlich kurz nachdenken, worauf Du hinauswillst. Ich meine zu ahnen, weshalb Du fragst.
    edit: ok, wenn sie im vector sind, ist es überflüssig sie erst zu deklarieren. Danke für den Hinweis.

    Die Konstante wird in all meinen Berechnungen benötigt. Wie meinst Du das, das ich mir über ihre Bedeutung nicht klar sein soll?



  • Brauchst du wirklich eine Konstante je Objekt (obwohl diese anscheinend immer den gleichen Wert hat) oder doch eher für die gesamte Klasse, also static const int zfactor = 200; (bzw. in einem anonymen Namespace nur in der Implementationsdatei)? Außerdem verhinderst du mit dieser Konstanten (als Member), daß die Klasse (standardmäßig) kopierbar ist (aber das kann natürlich auch Absicht von dir sein?). [Sorry, dies gilt ja nur für nicht-initialisierte const-Member...]



  • Ah, deshalb hast Du gefragt 😉 Gut, das werde ich mal ändern.

    Bin für weitere Hinweise weiterhin dankbar.


  • Global Moderator |  Mod

    Dies hier ist ein weiterer Code Smell, der noch nicht genannt wurde:

    @lemon03 sagte in Methoden einer anderen Klasse benutzen:

    AffineGraphic() {} //um ein Objekt in Shape zu erstellen

    Spezieller Defaultkonstruktor, damit eine andere Klasse dein Ding benutzen kann? Klingt eher danach, als würde die andere Klasse das falsch benutzen!

    Da sind noch weitere drin, die ich aber fachlich nicht beurteilen kann, da mir der Hintergrund fehlt, was hier überhaupt modelliert werden soll:

    • Shape hat sowohl eine Liste von CharPoint und Point, aber auch eine AffineGraphic, die wiederum aus Listen von CharPoint und Point besteht.
    • Die Klassen scheinen Darstellungslogik und mathematische Logik wild zu mischen


  • Jepp, dies gehört zum größerem Fragenkomplex. Würde gerne wissen, wie man dies korrekt macht.

    Gehört wahrscheinlich alles zum Design, so das ich an beiden Klassen größere Änderungen machen muss. Aber wie kann ich auch private ( gut, dies ist teilweise schon genannt worden) Methoden einer anderen Klasse benutzen. Es wird immer nur und ausschließlich vector<Point> und vector<Charpoint> in den betreffenden Methoden genutzt.

    Oder besser gefragt, wenn ich Methoden oder Funktionen habe, die immer mit den selben Vektoren die selben Berechnungen (abhängig von "persönlichen" Parametern) durch führe, wie bringe ich solche in Klassen unter?



  • Ich habe inzwischen ein Idee, wie ich das sauberer umsetzen kann...

    Kann mich ja dann wieder melden. Danke bis hier.


  • Global Moderator |  Mod

    Ratschlag: Was immer gut hilft, um recht einfach bei gut definierten und einsetzbaren Klassen zu landen, ist, dass jede Klasse genau eine Art von Ding aus der realen Welt beschreibt (oder auch aus der mathematischen Idealwelt). Damit vermeidest du solchen Quatsch, wie dass deine mathematischen Formen Zeichenmethoden haben. Hast du schon einmal einen (mathematischen) Kreis gesehen, der sich selber malt? Nein, ein Zeichner malt eine Näherung des mathematischen Idealkreises. Wahrscheinlich löst das auch ganz natürlich die komische Wahl deiner Member, die schon mehrmals angesprochen wurde. Was soll denn überhaupt eine AffineGraphic sein? Soll das eine mathematische Figur plus eine affine Transformation darauf sein? Dann mach das doch auch so!