C++ Schreib-still



  • hmm naja ,glaub ich hab wirklich eine große Diskussion eingeführt 😃

    Das mit setter/Getter ist wirklich etwas verwirrent vllt. verwende ich da mal andere Wörter für...

    Ahja und man wollte ein bisjen Code hab ich gelesen^^
    Hier mal eine TemplateKlasse die ich zur Übung geschrieben habe...

    // DAT.hpp
    #ifndef DAT_HPP_
    #define DAT_HPP_
    
    template <class DATA>
    class DAT
    {
    private:
       DATA Var;
    public:
       DATA getData() const;
       bool isEmpty();
       void setData(DATA Wert);
    };
    
    //----------> Getter! <----------//
    template <class DATA> 
    DATA DAT<DATA>::getData() const
    {
         return Var; 
    }
    
    //----------> Prüfer! <----------//
    template <class DATA> 
    bool DAT<DATA>::isEmpty()
    {
         if (Var == 0) {return true;}
         else {return false;}
    }
    
    //----------> Setter! <----------//
    template <class DATA> 
    void DAT<DATA>::setData(DATA Wert)
    {
         Var = Wert;
    }
    
    //----------> TheEnd! <----------//
    
    #endif
    

    Müsste eigentlich reichen...

    Mfg Wikinger75!



  • Tachyon schrieb:

    Shade Of Mine schrieb:

    ...

    Wenn Du es so pedantisch siehst, dann ging es auch nie darum, wie franz seine Impl-Klassen aufbaut, sondern darum, ob Stil des TOs (und nicht der von franz) gut ist.

    Wie langweilig...

    Aber gut, war nicht anders zu erwarten.

    Darf ich dennoch eine Antwort auf meine simple Frage bekommen oder ist das auch zu OT? Oder ist die antwort zu uninteressant, oder magst du mir das Bridge Pattern erklären?



  • Wikinger75 schrieb:

    hmm naja ,glaub ich hab wirklich eine große Diskussion eingeführt 😃

    Das mit setter/Getter ist wirklich etwas verwirrent vllt. verwende ich da mal andere Wörter für...

    Ahja und man wollte ein bisjen Code hab ich gelesen^^
    Hier mal eine TemplateKlasse die ich zur Übung geschrieben habe...

    // DAT.hpp
    #ifndef DAT_HPP_
    #define DAT_HPP_
    
    template <class DATA>
    class DAT
    {
    private:
       DATA Var;
    public:
       DATA getData() const;
       bool isEmpty();
       void setData(DATA Wert);
    };
    
    //----------> Getter! <----------//
    template <class DATA> 
    DATA DAT<DATA>::getData() const
    {
         return Var; 
    }
    
    //----------> Prüfer! <----------//
    template <class DATA> 
    bool DAT<DATA>::isEmpty()
    {
         if (Var == 0) {return true;}
         else {return false;}
    }
    
    //----------> Setter! <----------//
    template <class DATA> 
    void DAT<DATA>::setData(DATA Wert)
    {
         Var = Wert;
    }
    
    //----------> TheEnd! <----------//
    
    #endif
    

    Müsste eigentlich reichen...

    Mfg Wikinger75!

    a) Sehr unschöner Mix aus Englisch und Deutsch, sei konsistent!
    b) Sehr ungewöhnlich Methoden mit kleinen Buchstaben zu beginnen und Variablen mit großen
    c) MAN SCHREIBT NICHT KOMPLETT GROSS DAS IST SEHR SCHWER ZU LESEN UND DAHER NUR FÜR MAKROS SINNVOLL DAMIT MAN ES NICHT MIT IHREM EINSATZ ÜBERTREIBT
    d) isEmpty darf ruhig const sein und ihre Implementierung ist grauenhaft, vereinfache sie zu "return Var == 0;
    e) die Klasse ist so ziemlich sinnlos, sie scheint boost::optional imitieren zu wollen, aber nicht so wirklich konsequent damit zu sein, denn

    DAT< int > i; 
    i.setData( 0 );
    // btw. na fällt dir was auf?
    

    führt zu einem isEmpty() == false, dabei ist mein Objekt gar nicht leer.



  • Wenn einen Anwender das Aussehen nicht intressiert, warum ist es dann so wichtig für euch das public vor private steht ? 🙄 Ich finde bevor man Variablen benutzt, indem Falle Membervariablen, sollten sie über der Funktionalität stehen, damit man vorher sieht was existiert. Außerhalb einer Klasse oder einer Struktur muss eine Variable auch vor einer Funktion deklariert oder definiert sein, wieso dieses Schema in der Klasse dann verändern?



  • führt zu einem isEmpty() == false, dabei ist mein Objekt gar nicht leer.

    Ja wenn dein Objekt gar nicht leer ist dan mus ja false zurückgegeben werden^^



  • Wikinger75 schrieb:

    führt zu einem isEmpty() == false, dabei ist mein Objekt gar nicht leer.

    Ja wenn dein Objekt gar nicht leer ist dan mus ja false zurückgegeben werden^^

    Gemeint war natürlich isEmpty() == true.


  • Administrator

    Wikinger75 schrieb:

    hmm naja ,glaub ich hab wirklich eine große Diskussion eingeführt 😃

    Ich hab es ja gesagt, die Büchse der Pandora. Man kann mit Programmierer nicht vernünftig über dieses Thema diskutieren 🙂

    @Shade Of Mine,
    Ach, hack doch auf diesen Armen nicht so rum.

    @Arme, welche von Shade Of Mine in Stücke gehackt werden,
    Shade Of Mine wollte doch nur wissen, wie die Pimpl Klasse denn nun aufgebaut ist. Was wohl ziemlich schnell zum Schluss führen wird, dass sie genau gleich wie die normalen Klassen aufgebaut sind. Deswegen empfinde ich die Bemerkung von franz ziemlich überflüssig, denn irgendwo hat er seine Funktionen und co auch nach einem Schema organisiert. Oder hat er ein riesiges Durcheinander in der Pimpl Klasse, nur weil es eine Pimpl Klasse ist? Das würde ich als ziemlich dumm empfinden 🙂

    Grüssli



  • Ich persöhnlich hätte wahrscheinlich die Klasse so "designed"

    // DAT.hpp
    #ifndef DAT_HPP_
    #define DAT_HPP_
    
    template <class T> ///überlicherweiße nimmt man "T"
    class dat
    {
        private:
            T var;  ///var klein
        public:
            T getData() const;
            bool isEmpty() const; ///gibt nur etwas zurück, also const
            void setData(T); ///nur den Typ und nicht den Namen der Variable festlegen
    };
    
    //----------> Getter! <----------//
    template <class T> 
    T dat<T>::getData() const { return var; }
    
    //----------> Prüfer! <----------//
    template <class T>
    bool dat<T>::isEmpty() const
    {
         if (var == 0) { return true; }
         else { return false; } ///else ist nicht unbedingt notwendig
    }
    
    //----------> Setter! <----------//
    template <class T>
    void dat<T>::setData(T var) { this.var = var;} ///Klasse einsprachig lassen
    
    //----------> TheEnd! <----------//
    
    #endif
    


  • this.var = var;
    

    this ist doch ein Zeiger, müsste das den nicht so sein?

    this->var = var;
    


  • Wikinger75 schrieb:

    this.var = var;
    

    this ist doch ein Zeiger, müsste das den nicht so sein?

    this->var = var;
    

    Da hast du recht, der ist wahrscheinlich von seiner IDE verwöhnt 😃 😉

    FreakY<3Cpp schrieb:

    Ich persöhnlich hätte wahrscheinlich die Klasse so "designed"

    // DAT.hpp
    #ifndef DAT_HPP_
    #define DAT_HPP_
    
    template <class T> ///überlicherweiße nimmt man "T"
    class dat
    {
        private:
            T var;  ///var klein
        public:
            T getData() const;
            bool isEmpty() const; ///gibt nur etwas zurück, also const
            void setData(T); ///nur den Typ und nicht den Namen der Variable festlegen
    };
    
    //----------> Getter! <----------//
    template <class T> 
    T dat<T>::getData() const { return var; }
    
    //----------> Prüfer! <----------//
    template <class T>
    bool dat<T>::isEmpty() const
    {
         if (var == 0) { return true; }
         else { return false; } ///else ist nicht unbedingt notwendig
    }
    
    //----------> Setter! <----------//
    template <class T>
    void dat<T>::setData(T var) { this.var = var;} ///Klasse einsprachig lassen
    
    //----------> TheEnd! <----------//
    
    #endif
    

    Du hast jetzt nicht wirklich das Design geändert nur ein paar syntaktische und c++-spezifische Kleinigkeiten. Fundamentale Designfehler existieren weiterhin, wie man zum Beispiel in meinem Code-Snippet weiter oben sehen kann.

    Es zahlt sich aus zuerst einen Unit-Test für eine Klasse zu schreiben und dann diese zu implementieren, dann ergibt sich das öffentliche Interface auf natürliche Art und Weise.



  • FreakY<3Cpp schrieb:

    void setData(T); ///nur den Typ und nicht den Namen der Variable festlegen
    

    Warum?



  • 😮 sry, so eine Diskussion war nie meine Absicht...

    Dravere schrieb:

    @Arme, welche von Shade Of Mine in Stücke gehackt werden,
    Shade Of Mine wollte doch nur wissen, wie die Pimpl Klasse denn nun aufgebaut ist. Was wohl ziemlich schnell zum Schluss führen wird, dass sie genau gleich wie die normalen Klassen aufgebaut sind. Deswegen empfinde ich die Bemerkung von franz ziemlich überflüssig, denn irgendwo hat er seine Funktionen und co auch nach einem Schema organisiert. Oder hat er ein riesiges Durcheinander in der Pimpl Klasse, nur weil es eine Pimpl Klasse ist? Das würde ich als ziemlich dumm empfinden 🙂

    Also, prinzipiell schauen die private und die interface-header ähnlich aus. Mit dem einen unterschied dass die private eigentlich alles public haben (Zugriff hat ja eh nur die Q-Klasse).

    Und wenn der Kommentar überflüssig war, war es der auch auf den ich überhaupt geantwortet hab ("Private oben, da public-interface eh in der Doku steht"). Außerdem ist PIMPL selber in hohem Maße Übersicht fördernd, da einem die ganzen Member nicht ständig in der Quere sind (rein optisch), deshalb war der Kommentar auch nicht sooo überflüssig.



  • franz schrieb:

    Außerdem ist PIMPL selber in hohem Maße Übersicht fördernd, da einem die ganzen Member nicht ständig in der Quere sind (rein optisch), deshalb war der Kommentar auch nicht sooo überflüssig.

    Verstehe ich nicht. Warum kommen einem in der Impl Klasse die Member rein optisch nicht in die Quere?



  • Shade Of Mine schrieb:

    FreakY<3Cpp schrieb:

    void setData(T); ///nur den Typ und nicht den Namen der Variable festlegen
    

    Warum?

    Klar geht es, aber ich hab bisher noch nie in der Klasse den Variablennamen festgelegt.



  • Shade Of Mine schrieb:

    franz schrieb:

    Außerdem ist PIMPL selber in hohem Maße Übersicht fördernd, da einem die ganzen Member nicht ständig in der Quere sind (rein optisch), deshalb war der Kommentar auch nicht sooo überflüssig.

    Verstehe ich nicht. Warum kommen einem in der Impl Klasse die Member rein optisch nicht in die Quere?

    😕 Weil ein

    class Klasse {
    private:
       KlassePrivate* d;
    

    um einiges übersichtlicher ist als ein

    class Klasse {
    private:
       int m_length;
       int m_width;
       std::list<Pupil*> m_pupils;
       // und weitere Member
    

    Wenn man dann das private noch oben stehen hat kriegt man beim Blick in den Header echt nen Krampf. (Ganz zu schweigen von weiteren privaten Methoden samt kurzen Kommentaren).

    Im übrigen sollte es klar gewesen sein, dass ich nicht die Member der private-Klasse gemeint hab, sondern die der Interface-Klasse...



  • FreakY<3Cpp schrieb:

    Klar geht es, aber ich hab bisher noch nie in der Klasse den Variablennamen festgelegt.

    Mich würde das Warum interessieren...

    franz_ schrieb:

    😕 Weil ein

    class Klasse {
    private:
       KlassePrivate* d;
    

    um einiges übersichtlicher ist als ein

    class Klasse {
    private:
       int m_length;
       int m_width;
       std::list<Pupil*> m_pupils;
       // und weitere Member
    

    Wenn man dann das private noch oben stehen hat kriegt man beim Blick in den Header echt nen Krampf. (Ganz zu schweigen von weiteren privaten Methoden samt kurzen Kommentaren).

    Und wie sind dann KlassePrivate aus?
    Du brauchst int m_length und int m_width und m_pupils doch eh als Variablen. Klasse ist natürlich nur ein dummer proxy, aber mich interessiert das Layout in KlassePrivate. Dort hast du nämlich die ganzen privaten Funktionen und Member. Und das ist das interessante wie du sie dort angelegt hast.

    PS:
    deshalb fördert pimpl übrigens kein bisschen die Übersicht, weil du alles nur verschiebst. pimpl reduziert die abhängigkeiten - mehr aber auch nicht.



  • Ich glaube ich verstehe jetzt worauf Franz hinaus will und er würde in Java seine Schittstelle als interface schreiben und dieses dann implementieren, so trennt er effektiv die Implementierung von der Dokumentation der Schnittstelle.
    Könnte man in C++ auch so machen, allerdings hat man bei Pimpl auch gleich die Abhängigkeiten die die Implementierungsdetails mit sich bringen weg.



  • Tippgeber schrieb:

    Ich glaube ich verstehe jetzt worauf Franz hinaus will und er würde in Java seine Schittstelle als interface schreiben und dieses dann implementieren, so trennt er effektiv die Implementierung von der Dokumentation der Schnittstelle.
    Könnte man in C++ auch so machen, allerdings hat man bei Pimpl auch gleich die Abhängigkeiten die die Implementierungsdetails mit sich bringen weg.

    Natuerlich macht er das und pimpl macht ja auch Sinn. Aber darum geht es hier nicht. Es geht nicht um Bridge, Visitor, Pimpl, raii, etc. Sie alle machen Sinn.

    Aber hier geht es um den Coding Stil - um das Layout des Codes. Nicht das Design.

    Ist das so schwer zu verstehen?

    Deshalb nochmal:

    Coding Stil hat mit einrueckungen, namensgebung, reihenfolge der deklarationen, etc. zu tun und nichts mit bevorzugten design pattern. Deshalb:
    ich will wissen in welcher Reihenfolge die Elemente in der KlassePrivate vorkommen.

    Dort muessen Member Variablen und private bzw public Funktionen vorkommen. Die Reihenfolge dieser wuesste ich gerne - generell waere da ein Code Beispiel wie eben vom OP sehr nett anzusehen.

    Und nein, ich will nicht ueber Doc/View oder Adapter diskutieren, sondern einfach nur dummen sinnlosen Code sehen oder eine beschreibung wie er aussieht.



  • Shade Of Mine schrieb:

    Coding Stil hat mit einrueckungen, namensgebung, reihenfolge der deklarationen, etc. zu tun und nichts mit bevorzugten design pattern. Deshalb:
    ich will wissen in welcher Reihenfolge die Elemente in der KlassePrivate vorkommen.

    Dort muessen Member Variablen und private bzw public Funktionen vorkommen. Die Reihenfolge dieser wuesste ich gerne - generell waere da ein Code Beispiel wie eben vom OP sehr nett anzusehen.

    Und nein, ich will nicht ueber Doc/View oder Adapter diskutieren, sondern einfach nur dummen sinnlosen Code sehen oder eine beschreibung wie er aussieht.

    Um mein Beispiel aufzugreifen würde KlassePrivate etwa so ausschauen:

    class KlassePrivate {
    publilc:
       int length;
       int width;
       std::list<Pupil*> pupils;
       // und weitere Member
    

    Wenn ich auch Funktionen in KlassePrivate hab stehen die mit Leerzeilen getrennt VOR den Membervariablen.

    Es sollte klar sein, dass ein Blick in den Source nicht unbedingt den Wunsch bedeuten muss, zu sehen was "hinter der public-Schnittstelle" passiert (so wie du das ja auf Seite 2 andeutest). Denn die Member allein sagen ja noch herzlich wenig über (z.B.) Nebeneffekte von Funktionen aus. So was MUSS dokumentiert sein. Es kommt durchaus vor, dass Bibliotheken Closed Source sind, da kann man sich bei schlechter Dokumentation (oder überhaupt aus Interesse) mal die public Schnittstelle anschauen.
    Und allein hierauf war mein Kommentar bezogen, dass eigentlich die private Member auf den ersten Blick nicht interessieren. Und bei PIMPL steht halt dann einfach weniger im Header.
    Wenn der Source zur Verfügung steht, kann man sich doch auch sofort den private-Header holen und dann die Details rauspicken.

    Dass das allein kein Argument für dieses Idiom ist ist mir klar. Mir ist halt einfach dieser Punkt während der Diskussion hier aufgefallen.
    OK, ist vllt. kein gutes Beispiel, aber Qt wendet PIMPL ja an. Man stelle sich einfach mal vor, wie der Header von z.B. QWidget anschwillt, wenn da auch noch qwidget_p.h drin stehen würde (schlechtes Bsp. deshalb, weil die Doku einfach gigantisch ist...).

    Dass das aber nix mit Stil zu tun hat ist mir auch klar. Ich wollte hier auch nie eine Diskussion in diesen Ausmaßen anstoßen. Ich hab doch bloß auf diesen Beitrag geantwortet:

    Shade Of Mine schrieb:

    Aquae schrieb:

    Erst die public-Sachen, dann private... Den Benutzer kann ja nur das public interessieren

    Interessant, ich mache immer privat zuerst weil den Leser des Source Codes kann ja nur die interna interessieren - das public interface steht ja in der doku 😉

    Und wenn das in der Form ein Problem war tuts mir leid.



  • Kommentare wie "//----------> Getter! <----------//" sind für mich
    a) "noise"
    b) "undocumentation" (wassndas?)
    Finde ich garnicht gut.

    Wenn eine "optische Trennung" erwünscht ist, dann mach ich einfach ne Zeile

    /////////////////////////////////////////////////////////////////////////
    

    und gut is.

    Wenn wir allerdings zwischen jeder Funktion so eine Zeile einziehen ... sind wir schnell wieder beim Thema "noise".


Anmelden zum Antworten