Viele private Funktionen in Klasse schlechter Stil??



  • Killerqueen schrieb:

    Das kling gut 🙂
    Und was mache ich wenn es keine logische Aufteilung gibt? Also bei Hund Astronaut etc ist es ja noch recht eindeutig .... gibt es da vielleicht Tricks? 😕
    Entschuldige meine Einfallslosigkeit! Mir fällt gerade kein passendes Beispiel ein.

    Du liest Dir die Spielregeln durch und nimmst die Begriffe raus, das werden die Klassen. Naja, so ungefähr. Es wäre gut, wenn Du es mal eine Weile lang übertreiben würdest, also zu viele zu kleine Klassen machen. Wenn DU dann beide Welten kennst, schlägst Du einen gesunden Mittelweg ein. Der wird aber "Ein Zweck - eine Klasse!" als wesentliches Merkmal immer behalten.

    Ach ja, und alle Generalisierungen sind falsch. Egal, was Du beim Programmieren dogmatisch durchziehst, es wird suboptimal werden. Experimentiere rum und mach am Ende das, was zu den wenigsten Fehlern und Schreibblockaden führt.



  • Super!
    Aber wenn ich so viele Klassen verwende kann es doch unter Umständen vorkommen dass diese keine member-Daten enthalten?
    Sind das dann schon zu viele Klassen?
    Ist so eine Klasse generell sinnvoll?



  • Killerqueen schrieb:

    Ist so eine Klasse generell sinnvoll?

    Nein, meistens eigentlich nicht. Wenn die Klasse nur Funktionen anbietet, können diese normalerweise auch ebenso gut global sein (unter Umständen in einem Namensraum). Denn eine Instanz von so einer Klasse repräsentiert meistens nichts.

    (Ausnahmen wie zum Beispiel in der Metaprogrammierung gibt es natürlich immer, aber die sind hier nicht gross von Bedeutung.)



  • (Ausnahmen wie zum Beispiel in der Metaprogrammierung gibt es natürlich immer, aber die sind hier nicht gross von Bedeutung.)

    Es gibt nochmal eine Ausnahme, welche mir nicht unwichtig erscheint.
    Na, was hat Funktionen, aber keine Datenmember? - Die kennen wir doch alle.
    Genau. Abstrakte Basisklassen. 🙂

    Das sind jetzt weniger Klasse im Sinne des TO's, aber imo dennoch nicht ausser Acht zu lassen.



  • Stimmt, hab ich völlig vergessen, interfacemässige Klassen. Danke für den Nachtrag. 🙂



  • So nun noch eine konkrete Frage:
    Ich habe für eine member-Funktion eine Hilfsklasse definiert die 2 Zeiger managet.
    Meine Funktion braucht als ARgument eine Refernez vom eigenen Typ:
    bool raumfaehre::kollidiere(raumfaehre&);
    Daher ist Pro raumfaehre eine Hilfsklasseninstanz nötig.

    <b>Ist es sinnvoll die Funktionalität in die Klasse raumfaehre zu packen und dabei diese um 2 Zeiger schwerer zu machen, welche nur für die eine Funktion und ihrer Unterfunktionen benötigt werden?</b>

    Oder soll ich ganz auf Komfort setzen und jede Hilfsklasse per member varible auf eine raumfaehre beziehen:

    Also statt:

    bool raumfaehre::kollidiere(raumfaehre& raumfaehreB)
    {
       kollisionshelferA.berechne_bahn( *this );
       kollisionshelferB.berechne_bahn( raumfaehreB );
    
       //oder
    
       kollisions_helfer_t kollisionshelferA(this);
       kollisions_helfer_t kollisionshelferB(&raumfaehreB);
    
       kollisionshelferA.berechne_bahn();
       //...
    }
    

    Ich brauche für die Aufgabe bestmögliche Performance!

    Oder ist sowas eigendlich egal?!

    😕 😕 😕



  • Wenn bei der Kollision beide beteiligten Objekte gleich behandelt werden (es also keine Rolle spielt, ob A mit B kollidiert oder B mit A), würde ich eher eine globale Funktion als eine Memberfunktion nehmen:

    void kollidiere(raumfaehre& a, raumfaehre& b);
    

    Zu deinen Kollisionshelfern: Da glaube ich, nicht ganz alles verstanden zu haben. Sind die global oder woher kennt sie die Funktion? Ist eine Raumfähre immer an einen Kollisionshelfer (z.B. über einen Zeiger) gebunden? Oder was für eine Beziehung (auch semantisch, nicht nur technisch) gibt es da?



  • Nun, die beiden Helfer werden innerhalb der Kollisionsfunktion lokal instanziiert.
    Bei der Kollision wird jedes Polygon von Fähre A mit B getestet ob sie sich schneiden/berühren.
    Dabei brauche ich 2 Zeiger auf die Kanten der Polygone, welche das gegnerische Polygon berührt oder schneidet..... jedenfalls muss viel mit den Zeigern hantiert werden darum habe ich eine extra Klasse dafür erstellt....

    Gegen die globale Funktion würde ich folgendes einwenden:
    da sie exzessiv raumfaehren-Daten benötigt müsste ich sie als friend deklarieren was ich irgendwie hässlich finde 😃



  • Killerqueen schrieb:

    Gegen die globale Funktion würde ich folgendes einwenden:
    da sie exzessiv raumfaehren-Daten benötigt müsste ich sie als friend deklarieren was ich irgendwie hässlich finde 😃

    Wahrscheinlich hast du noch keine richtige Schnittstelle für deine Raumfähren eingerichtet.

    friend sollte nicht nötig sein, wenn man Get-/Set-Funktionen zur Verfügung stellt. Meist ist es auch sicherer und besser wartbar, wenn von aussen über Funktionen zugegriffen wird. Zum Beispiel kannst du dann Zugriffe mitloggen.

    Und zu den exzessiven Daten: Du musst ja nicht Dutzende von Funktionen anbieten. Eine Idee wäre eine kleine Struktur, zum Beispiel CollisionData , die für die Kollision wichtige Attribute zusammenfasst.



  • Hmmm ... 😃 ... mir fällt gerade ein:
    Nach einer Kollision bleibt nur eine Fähre übrig also muss die zweite ohnehin deletet werden. Vielleicht ist dann eine nicht-globale Lösung besser?

    Aber bei all dem bleibt dann noch das Problem mit meiner Hilfsklasse!!!!
    Diese behinhaltet nämlich jeweils 2 KANTEN eines Polygons und muss lauter für die Kollision spezifische Sachen machen .... 😕



  • Killerqueen schrieb:

    Vielleicht ist dann eine nicht-globale Lösung besser?

    Nein, a.kollidiere(b) bleibt ja nach wie vor das Gleiche wie b.kollidiere(a) . Darum geht es eigentlich. Wenn die Funktion nicht symmetrisch wäre, also zum Beispiel immer die übergebene Raumfähre zerstört würde, wäre das wieder etwas anderes.

    Du sagst ja auch nicht "b wird von a kollidiert". Entweder "a und b kollidieren" oder "a kollidiert mit b", bei letzterem könnte man aber ebenso gut "b kollidiert mit a" sagen. Ich habe hier natürlich vorausgesetzt, dass die Semantik wirklich gleich bleibt, wenn man die Argumente vertauscht.

    Killerqueen schrieb:

    Aber bei all dem bleibt dann noch das Problem mit meiner Hilfsklasse!!!!
    Diese behinhaltet nämlich jeweils 2 KANTEN eines Polygons und muss lauter für die Kollision spezifische Sachen machen .... 😕

    Aber eben, kannst du die Schnittstelle nicht entsprechend anpassen? Zum Beispiel so:

    struct physikdaten
    {
        // physikalische Dinge wie Position, Geschwindigkeit, ...
        // halt welche Eigenschaften für Kollision relevant sind.
    };
    
    class raumfaehre
    {
        public:
            const physikdaten& get_kollisionsdaten() const;
            void               set_kollisionsdaten(const physikdaten& daten);
        private:
            physikdaten        meine_physik;
    };
    
    class kollisionshelfer
    {
        public:
                               kollisionshelfer(raumfaehre& bezugsobjekt);
            void               berechne_schaden();
            void               schleudere_astronauten_ins_all();
    
         private:
            raumfaehre&        meine_faehre;
    };
    

    Nur so ein Vorschlag, ich weiss zu wenig Konkretes über dein Design. Intern könnte der Kollisionshelfer dann auf die Getter und Setter der Raumfähre zugreifen.


Anmelden zum Antworten