Für jede Klasse eine Headerdatei oder mehrere in einer?



  • Hallo,

    wie handhabt ihr das mit der Aufteilung eures Projektes in einzelnen Dateien?

    - Für jede Klasse eine Headerdatei und eine Implementierungsdatei
    - Eine Klasse gleich in der Headerdatei
    - Mehrere Klassen in einer Header- und Implementierungsdatei
    - Mehrere Klassen in nur eine Headerdatei

    Vielleicht könnte ihr eure Antwort auch begründen. Ich bin der Meinung mal gelesen zu haben, dass es heutzutage kaum noch Gründe gibt jede Funktion oder Klasse in eine extra Header- und Cpp Datei zu packen. Obwohl ich es auch übersichtlicher finde zu trennen neigen ich persönlich doch dazu jede Klasse in eine Headerdatei zu packen, da die Projekte eh nie sehr groß sind und ich auch nur für mich selbst programmiere und nicht vor habe die Sources irgendwie zu veröffentlichen.

    Wie macht ihr das?

    G hibbes



  • Ich bin für Variante A.



  • Variante A ist immer richtig, außer beim templates, da ist Variante B richtig.



  • Hallo,

    grundsätzlich verwende ich die Regel:
    Jede Klasse bekommt eine eigene Headerdatei und (falls erforderlich) eine eigene Quelldatei.

    Aber wenn ich mehrere kleine Klassen habe, die logisch zusammengehören und die Übersicht nicht darunter leidet, dann fasse ich diese auch schon mal in einer Header nzw. Quelldatei zusammen.

    Umgekehrt hatte ich aber auch schon den Fall, daß eine Memberfunktion einer Klasse eine andere Klasse instanziert hat und der verwendete Compiler bzw. Linker nicht in der Lage war, diese Memberfunktion zu ignorieren, wenn sie nicht aufgerufen wurde. Dann wurde das Executable deutlich größer, weil auch die andere Klasse mit hinzugebunden wurde. Deshalb habe ich diese eine Memberfunktion in eine extra Quelldatei ausgelagert.

    mfg Martin



  • Ich möchte nur mal kurz einen anderen Standpunkt vorstellen:

    Wenn man sich bei Python die Modules anschaut, ist es eher typisch ein Modul für z.B. Geometry zu haben, in das dann Line, Circle usw. Klassen kommen.

    geometry.py

    class Line:
       ...
    
    class Circle:
       ...
    

    Anwendung

    from geometry import Line, Circle
    
    ...
    

    Ähnlich kann man das auch in C++ machen:

    geometry.hpp

    namespace geometry {
       class Line { ... };
       class Circle { ... };
    }
    

    Anwendung

    #include "geometry"
    
    using geometry::Line;
    using geometry::Circle;
    
    ...
    

    Finde ich dann eigentlich ganz schick, und solange nicht gerade 20 große Klassen in geometry.hpp kommen praktischer.



  • Ups, sollte natürlich

    #include "geometry.hpp"
    

    heißen.
    Die Implementierung von Line und Circle kann man dann natürlich entweder in eine geometry.cpp, oder in zwei verschiedene line.cpp und circle.cpp Dateien stecken, aber das ist ja jederzeit ohne großen Aufwand austauschbar und kann je nach Geschmack gemacht werden.



  • Ich mache grundsätzlich eine Headerdatei pro Klasse. Dann hat's einfach mehr Ordnung und ich kann Sachen leichter auch mal ohne IDE finden. Und ich kann gezielter inkludieren und Compilezeit sparen. Und ich kann vielleicht mal eine Klasse klauen und im anderen Projekt nehmen. Also eigentlich kein wichtiger Vorteil. Aber ich muß einfach weniger nachdenken übder die ganze Geschichte. *Das* ist der Vorteil daran.

    Ich treibe es so weit, daß ich, wenn ich der Post und mir nicht vertraue und einen eigenen Typ für Postleitzahlen brauche, aber eigentlich string schon reicht, auch eine Headerdatei mit nur einer Zeile schreibe

    #ifndef ...
    #define ...
    
    #include <string>
    
    typedef std::string Postleitzahl;
    
    #endif
    


  • volkard schrieb:

    ...

    #ifndef ...
    #define ...
    
    #include <string>
    
    typedef std::string Postleitzahl;
    
    #endif
    

    🙄



  • nichtDeinErnst? schrieb:

    volkard schrieb:

    ...

    #ifndef ...
    #define ...
    
    #include <string>
    
    typedef std::string Postleitzahl;
    
    #endif
    

    🙄

    Ich schließe mich dem an: Nicht dein Ernst, oder?

    Das man eigene Typen auslagert, mag ich noch als sinnvoll erachten, aber den typedef finde ich überflüssig.

    Irgendwann sieht das so aus:

    typedef std::string Text;
    typedef Text Postleitzahl;
    typedef Text Bankverbindung;
    typedef Text Name;
    typedef Name Vorname;
    typedef Name Nachname;
    

    Grausam. 😃



  • ich dachte eher daran, dass
    "In Deutschland sind Postleitzahlen seit dem 1. Juli 1993 5-stellig"
    also nehme ich ein char* und kein std::string! das ist wie mit kanonen auf spatzen zu schießen...



    1. Juli 1993 schrieb:

    ich dachte eher daran, dass
    "In Deutschland sind Postleitzahlen seit dem 1. Juli 1993 5-stellig"
    also nehme ich ein char* und kein std::string! das ist wie mit kanonen auf spatzen zu schießen...

    Genau char[5]. Und 2025 werden sie 6-Stellig? Dann darf ich wie die Opfer-Programmierer damals beim y2k-Problem tausende von Dateien sichten.

    Naja, string ist erstmal ok. Wenn ich dann Zeit und Lust habe, kann ich ja noch ein wenig an der Performanz popeln und char* oder char[] oder uint_32 nehmen. Ich KANN, weil ich es eingeplant habe (*mir mal selber auf die Schulter klopf*).



  • evtl. könnt mans auch mal mit nem int probieren das wären nochmal -20% und natürlich sortiert sich sowas dann auch leichter. aber das wisst ihr ja schon alle dafür habt ihr ja studiert...



  • int0r schrieb:

    evtl. könnt mans auch mal mit nem int probieren das wären nochmal -20% und natürlich sortiert sich sowas dann auch leichter.

    Jaja, dann fügt man bei der Ausgabe noch führende Nullen ein, weil du die in einer Ganzzahl nicht speichern kannst, und dann brauchts nur noch einen, der eine alte Postleitzahl eingibt, wenns kein /^\d{5}$/.match(plz) gibt.



  • int0r schrieb:

    evtl. könnt mans auch mal mit nem int probieren das wären nochmal -20% und natürlich sortiert sich sowas dann auch leichter. aber das wisst ihr ja schon alle dafür habt ihr ja studiert...

    Noch die Ausgabe für meine Freunde in Uhyst fünfstellig machen...
    Mhh. Wie mache ich das bloß? Eine struct draus machen und den op<< überladen?Oder per Hand einfach immer für Fünfstelligkeit sorgen und nie vergessen.



  • volkard schrieb:

    ...Und 2025 werden sie 6-Stellig? Dann darf ich wie die Opfer-Programmierer damals beim y2k-Problem tausende von Dateien sichten...

    eher werden die im jahr 10000 5-stellig und dann wird wieder gesichtet...



  • uups.



  • kurzeInfo schrieb:

    eher werden die jahreszahlen im jahr 10000 5-stellig und dann wird wieder gesichtet...



  • Michael E. schrieb:

    und dann brauchts nur noch einen, der eine alte Postleitzahl eingibt, wenns kein /^\d{5}$/.match(plz) gibt.

    vor ungültigen daten in deinen datensätzen schützt dich auch kein std::string...


  • Mod

    erkennerSchlechtenCodes schrieb:

    Michael E. schrieb:

    und dann brauchts nur noch einen, der eine alte Postleitzahl eingibt, wenns kein /^\d{5}$/.match(plz) gibt.

    vor ungültigen daten in deinen datensätzen schützt dich auch kein std::string...

    Doch! Denn bei std::string man kann erkennen, ob eine 4 oder eine 5 stellige Postleitzahl eingegeben wurde, bei int nicht.

    Postleitzahlen sind nun einmal keine Zahlen, sondern Ziffernfolgen, auch wenn der Name etwas anderes suggeriert. Daher immer den richtigen Datentyp wählen.



  • also ich halt mich jetzt raus mir ist das zu blöd. es ist keine diskussion das in eine eigene datei auszulagern und auch ein eigener datentyp ist dafür ok. aber kein std::string 😡


Anmelden zum Antworten