Quellcode Organisation



  • Ich wollte mal fragen, wie man seine Header und Source Dateien in C++ am besten organisiert. Macht man das einfach mit Unterverzeichnissen?

    In Java gibt es ja packages, mit denen man Hierarchien bilden kann, gibt es da etwas äquivalentes auch in C++?

    Ich habe in einem anderen Forum folgende Zeile Quellcode gefunden

    bool GUI::ButtonImageWidget::isInside(SDL::SPoint p)
    

    das sieht ja schon sehr nach Hierarchie aus, läuft das nur über namespaces oder wie kommt die Schachtelung da zustande?



  • Naja, ich würde mal raten, dass GUI:: ein Namespace ist, und isInside() eine statische Methode von der Klasse ButtonImageWidget ist^^



  • GUI wird ein namespace sein, ja. Das hat aber alles nichts mit der "physischen" Organisation zu tun, das bleibt ganz dir überlassen. Du kannst alles in eine einzige Datei packen, eine Datei pro Methode oder Funktion, was auch immer.

    In der Regel bietet sich folgende Struktur an:

    /src/some_namespace/class_foo.hpp
    /src/some_namespace/class_foo.cpp
    /src/some_namespace/modul_bar.hpp
    /src/some_namespace/modul_bar.cpp
    /src/some_namespace/nested_namespace/class_whatever.hpp
    /src/some_namespace/nested_namespace/class_whatever.cpp
    /src/another_namespace/class_smth.hpp
    /src/another_namespace/class_smth.cpp
    /etc.
    


  • The-Kenny schrieb:

    isInside() eine statische Methode von der Klasse ButtonImageWidget ist^^

    Mit 99.9...% Sicherheit nicht.



  • finix schrieb:

    GUI wird ein namespace sein, ja. Das hat aber alles nichts mit der "physischen" Organisation zu tun, das bleibt ganz dir überlassen. Du kannst alles in eine einzige Datei packen, eine Datei pro Methode oder Funktion, was auch immer.

    Okay, danke erstmal soweit.

    Was ich noch gerne wissen würde, wäre, wie man eine Klasse in den namespace einer anderen Klasse packt. Macht man das mit "using"?

    Bis jetzt wusste ich nur, daß jede Klasse nen eigenen Namespace hat, in dem dann Variablen und Funktionen liegen, aber dass man Klassen in den namespace einer Oberklasse packen kann, verwundert mich etwas...



  • Namespace ist ja keine Klasse.
    Es ist nur ein eigener Bereich, wie das ja der Name schon sagt.
    Definieren tust du das so:

    namespace foo
    { 
       class bar()
       {
       };
    }
    

    Jetzt gehört die Klasse bar zum Namespace foo.
    Willst du bar jetzt in einem anderen bereich verwenden musst du so schreiben:

    foo::bar myClassObject;
    

    Willst du nicht immer das foo:: schreiben, packst du am Anfang der Datei einfach:

    using namespace foo
    

    Damit machst du den Namensbereich dem Compiler bekannt und er sucht alle verw. Typen und Klassen auch in diesem Bereich. So verständlich?

    edit:
    Noch ein Trick. Hat ein Namespace nen elends langen namen, du willst aber kein "using" verwenden geht auch folgendes:

    namespace kurz = elendslangernamespacedenkeinmenschschreibenwill
    // dann ist 
    kurz::foo() 
    //das selbe wie
    elendslangernamespacedenkeinmenschschreibenwill::foo()
    

    Und den Namespace kannst du zur Definition in jeder Beliebiger Datei verwenden. Das ist nicht zusammenhängend wie bei Java ;).

    Die Physische Organisation von Daten ist dir überlassen. Eine gängige Methode ist es, bei Libs extra Ordner für Source und Header zu verwenden. Andere packen jede Klasse in einen eigenen Ordner, andere sortieren nach der Funktionalität der Dateien etc etc.
    rya.



  • Scorcher24 schrieb:

    namespace kurz = elendslangernamespacedenkeinmenschschreibenwill
    // dann ist 
    kurz::foo() 
    //das selbe wie
    elendslangernamespacedenkeinmenschschreibenwill::foo()
    

    Nur Interessehalber: geht dann auch sowas:

    namespace top {
      namespace bottom {
        namespace deeper {
          namespace stilldeeper {
            namespace core {
              struct foo;
            }
          }
        }
      }
    }
    
    namespace short = top::bottom:deeper::stilldeeper::core; //geht das?
    using short::foo;
    


  • Ja.



  • Klar, geht das.
    Bis auf namespace short. Weil short ist ein keyword von C++. 😃 Aber das is jetzt Erbsenzählerei *g*.
    rya.

    Edit: Wenn du aber sowas machen willst, geh ins Java-Forum :P. Ich hab noch kein C++-Produkt mit solch extrem verschachtelten Namespaces gesehen. 😉



  • Ich hab noch kein C++-Produkt mit solch extrem verschachtelten Namespaces gesehen.

    Aber es kommt langsam in Mode !

    Haben schon von externen zulieferern Interfaces mit namespaces in der 5. oder 6. ebene bekommen 🙂

    Ciao ...



  • RHBaum schrieb:

    Ich hab noch kein C++-Produkt mit solch extrem verschachtelten Namespaces gesehen.

    Aber es kommt langsam in Mode !

    Haben schon von externen zulieferern Interfaces mit namespaces in der 5. oder 6. ebene bekommen 🙂

    Ciao ...

    Gnaahh, ich hasse es ehrlich gesagt. Vor allem wenn dann die Libs noch so tolle namen wie System oder CSystem verwenden, innerhalb Ihrer Namespaces. Wenn man dann using verwendet, haut mir das jedesmal Intellisense auseinander.. -.-
    rya.



  • finix schrieb:

    GUI wird ein namespace sein, ja. Das hat aber alles nichts mit der "physischen" Organisation zu tun, das bleibt ganz dir überlassen. Du kannst alles in eine einzige Datei packen, eine Datei pro Methode oder Funktion, was auch immer.

    In der Regel bietet sich folgende Struktur an:

    /src/some_namespace/class_foo.hpp
    /src/some_namespace/class_foo.cpp
    /src/some_namespace/modul_bar.hpp
    /src/some_namespace/modul_bar.cpp
    /src/some_namespace/nested_namespace/class_whatever.hpp
    /src/some_namespace/nested_namespace/class_whatever.cpp
    /src/another_namespace/class_smth.hpp
    /src/another_namespace/class_smth.cpp
    /etc.
    

    Mal ne Frage dazu: Wenn ich das so machen würde, wie wären dann die Einstellungen die #includes betreffend?

    Ich verstehe im Moment leider noch net ganz, wie include nach den Dateien sucht, es gibt ja

    #include <blabla>
    

    was im include Verzeichnis des Compilers nach der Datei sucht und

    #include "blabla"
    

    was im aktuellen Verzeichnis nach blabla sucht.

    Beides passt ja erstmal nicht bei der Benutzung von Unterverzeichnissen, vor allem wenn die main selbst in nem Unterverzeichnis liegt oder eine Datei ne andere einbinden will, die auf einer höheren Verzeichnisebene liegt...
    Oder habe ich da jetzt was falsch verstanden?



  • mit #include "..\\bla.h" wird im übergeordneten Verzeichnis nach der Datei gesucht, ebenso kannst du Unterverzeichnisse angeben: #include "subdir\\kraks.h" . So kannst du überall-hin navigieren.



  • Na, da gibst du dann halt einfach den relativen Pfad an.

    Innerhalb des Projektes kannst du sowas machen:

    #include "some_namespace/class_foo.hpp"
    


  • Badestrand schrieb:

    mit #include "..\\bla.h" wird im übergeordneten Verzeichnis nach der Datei gesucht, ebenso kannst du Unterverzeichnisse angeben: #include "subdir\\kraks.h" . So kannst du überall-hin navigieren.

    Also Backslash ist ja wohl ganz böse. Benutze doch bitte einfach Slashs... das geht auch auf einem Windows-Compiler.



  • Artchi schrieb:

    Badestrand schrieb:

    mit #include "..\\bla.h" wird im übergeordneten Verzeichnis nach der Datei gesucht, ebenso kannst du Unterverzeichnisse angeben: #include "subdir\\kraks.h" . So kannst du überall-hin navigieren.

    Also Backslash ist ja wohl ganz böse. Benutze doch bitte einfach Slashs... das geht auch auf einem Windows-Compiler.

    Fördert vor allem die Portabilität des Codes auf andere Systeme.

    @Topic
    Wie du das mit dem Verzeichnissen machst, ist auch wieder Geschmackssache ;).
    Ich hab bei meiner Lib folgendes layout:

    [ÜberVerzeichniss]
    - [ProjektVerzeichniss]
    - [src] <- enthält nur .cpp dateien
    - ProjektDatei.vcproj
    - [include]
    - DieselTool.h <- enthält einen allgemeinen header, der alles includiert
    - inc <- enthält .h dateien
    [end]

    In der Projekt-Datei includiere ich alle Dateien mit "inc/foo.h". Das Verzeichnis include ist in der Projektdatei als zus. include-pfad angegeben.
    Also kann ich mit <inc/foo.h> einfach die dateien zufügen.
    rya.



  • Badestrand schrieb:

    mit #include "..\\bla.h" wird im übergeordneten Verzeichnis nach der Datei gesucht, ebenso kannst du Unterverzeichnisse angeben: #include "subdir\\kraks.h" . So kannst du überall-hin navigieren.

    Das mit über- und untergeordneten Verzeichnissen verstehe ich so leider nicht, das Beispiel ist etwas zu abstrakt für mich.

    Wenn ich jetzt im Verzeichnis Source\UI\HUI eine Datei liegen habe und eine Datei im Verzeichniss \Source\app includen will, wie lautet dann die Anweisung?



  • Na, das sind doch ganz normale Kommandozeilen-Kenntnisse aus der Windows- und Unix-Welt! 😮

    Ein Verzeichnis hoch wechseln:

    cd ..
    

    Eine Datei aus dem oben liegendem Verzeichnis starten:

    ../start.exe
    

    Noch nie nen Computer benutzt? 😉

    Nichts anderes passiert in der Include-Anweisung.

    #include "../gui/button.hpp" // aus dem aktuellen Verzeichnis eins hoch, in gui rein, dort button.hpp benutzen
    
    #include "../../gui/button.hpp" // aus dem aktuellen Verzeichnis zwei hoch, in gui rein, dort button.hpp benutzen
    
    #include "./gui/button.hpp" // aus dem aktuellen Verzeichnis in gui rein, dort button.hpp benutzen
    
    #include "gui/button.hpp"  // das gleiche wie mit ein punkt
    


  • AAAARGH...

    Ja doch, schonmal nen Computer benutzt, aber die Doppelpunkte als "da könnte nochmehr stehen" interpretiert, und nicht als Teil des Kommandos...



  • Artchi schrieb:

    Badestrand schrieb:

    mit #include "..\\bla.h" wird im übergeordneten Verzeichnis nach der Datei gesucht, ebenso kannst du Unterverzeichnisse angeben: #include "subdir\\kraks.h" . So kannst du überall-hin navigieren.

    Also Backslash ist ja wohl ganz böse. Benutze doch bitte einfach Slashs... das geht auch auf einem Windows-Compiler.

    Ich benutze auch immer normale Slashs. War mir nur nicht mehr sicher, ob das auch unter Linux geht, hab dann einfach mal einen Backslash gemacht 🤡
    edit: Wegen dem von wegen Linux nimmt eine Art, Windows beide weils die eine patentiert hat.. 🙄


Anmelden zum Antworten