C++ Schreib-still



  • 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".



  • @Shade Of Mine:
    Ich schätze du willst eigentlich wissen wie franz das macht, aber ich schreib trotzdem einfach mal wie sowas bei mir aussieht:

    #pragma once
    
    #include "Common.h"                // anm: erst "meine" header
    #include "WasIchNochBrauch.h"
    
    #include <cryptopp/blah.h>         // anm: dann "andere" header (diverse libs)
    #include <boost/noncopyable.h>
    
    #include <windows.h>               // anm: dann "standard" header
    #include <algorithm>
    
    namespace Blubb
    {
    
    ///////////////////////////////////////////////////////////////////////////
    
    class Foo:
        public XYZ,
        private boost::noncopyable
    {
        friend Bar;
    public:
        //! doku
        Foo();
    
        //! doku
        Foo(P1 p1, P2 p2);
    
        ~Foo(); // anm: bekommt sicher keine doku wenn's hier nicht was ganz seltsames zu beachten gibt
    
        size_t GetWidth() const;  //!< doku
        size_t GetHeight() const; //!< doku
    
    private:
        void Fun() const;
        void Joy();
    
        static void JoyJoyHappyHappyJoyJoy();
    
        class InnerClass
        {
            // ...
        };
    
        size_t m_width;   //!< doku
        size_t m_height;  //!< doku
        boost::shared_ptr<InnerClass> m_inner;
    };
    
    } // namespace Blubb
    


  • FreakY<3Cpp schrieb:

    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.

    Das ist doch der Blanke Horror (tm)!

    Wenn ich in ein Header-File reingucke, dann will ich wissen was es für Funktionen gibt, was die machen, und welcher Parameter welcher ist.
    Wenn da keine Namen dabeistehen... toll. Ausserdem können die meisten IDEs Header-Files parsen und hübsche Hilfsfenster einblenden.
    Hilft mir aber wenig wenn in dem Hilfsfenster dann keine Parameter-Namen stehen.

    Und vonwegen festlegen: du legst garnix fest, du kannst bei der Implementierung einen ganz anderen Namen verwenden:

    //header:
    void Foo(int dasWasAusgedrucktWerdenSoll);
    
    //impl:
    void Foo(int v)
    {
        printf("%d\n", v);
    }
    


  • Bei mir kommt public immer zu erst.

    irgendwas.hpp
    
    class Manager
    {
    
        public:
    
      	// Ctor
    	// *@param none
        Manager();
    
    	// Dtor
    	// *@param none
        ~Manager();
    
    	// Call to initialize Manager
    	//	*@param name player name
    	//	*@return reference to this
        Manager& Init( const std::string & name);
    
        protected:
        // ....
    
        private:
        // ....
    };
    


  • Noch vergessen zu erwähnen, dass mein Schreibstil natürlich am Schönsten ist.


Anmelden zum Antworten