Namepspaces in Verzeichnishierarchie darstellen



  • Ich möchte bei mir gerne folgende Namespaces (mit entsprechenden Unternamespaces) einrichten:

    • fun (fun::test::threadtest) | (fun::alcatraz)
    • util (util::position)
    • work

    In der Verzeichnisstruktur sieht dass dann so aus:

    .
    |-- fun/
    |   |-- test/
    |   |   |-- threadtest/
    |   |   |   `-- thread.cpp
    |   |    `-- [b]hui.cpp[/b] [i]//in hui.cpp möchte ich position.h inkludieren.[/i]
    |   `-- alcatraz/
    |       |-- alcatraz*
    |       |-- alcatraz.cpp
    |       |-- alcatraz.h
    |       |-- ausgabe.txt
    |       |-- experiment.cpp
    |       |-- insasse.cpp
    |       |-- main.cpp
    |       |-- makefile
    |       |-- raum.cpp
    |       `-- registrator.cpp
    |-- util/
    |   `-- position/
    |       |-- position.cpp
    |       `-- [b]position.h[/b]
    `-- work/
    

    Wie mache ich jetzt aber der Klasse position in der Datei position.h klar,
    dass sie sich im Namespace util::position befindet.

    #ifndef POSITION_H__  // Warum eigentlich nicht __POSITION_H__ ??
    #define POSTTION_H__                    
    
    //Bitte auf keinen Fall über den Sinn dieser Klasse
    //nachdenken. Es geht hier nur um's Prinzip! 
    
    namespace util::position
    {
      struct pos 
      {
        int npos1;
        int npos2;
      };
      typedef struct pos pos;
    
      class position                                                                      
      {                                                                                   
        public:                                                                           
          position(int, int);
          virtual ~position();                                                            
    
          const pos getPosition() const ; 
          void getPosition(int*, int*) const;                                             
    
       private:
         int m_pos1;                                                                     
         int m_pos2;                                                                     
      };
    }                                                                                   
    #endif
    

    In der cpp stelle ich mir das so vor:

    #include "position.h"                                                               
    
    using namespace util::position;                                                      
    
    position::positon(int a, int b)                                                   
    {                                                                                   
      m_npos1 = a;                                                                      
      m_npos2 = b;                                                                      
    }                                                                                   
    
    virtual position::~position() {}                                                    
    
    void position::getPosition(int* a, int* b) const                                    
    {                                                                                   
      if(!a || !b)                                                                      
        return;                                                                         
    
      *a = m_npos1;                                                                     
      *b = m_bpos2;                                                                     
    }                                                                                   
    
    const pos position::getPosition() const                                                   
    {                                                                                   
      pos posi;                                                                         
      posi.pos1 = m_npos1;                                                              
      posi.pos2 = m_npos2;                                                              
      return posi;                                                                      
    }
    

    Wie binde ich diese Klasse position denn jetzt ein?
    Nehmen wir mal an, ich würde in "hui.cpp" die Klasse util::position::position brauchen.

    //hui.cpp
    #include <iostream>
    
    #include "util/position/position.h"
    using util::position::position;
    using util::position::pos;
    
    int main()
    {
      position Pos(7,8);
      pos __POSI = Pos.getPosition();
      std::cout << __POSI.npos1 << " " << __POSI.npos2 << std::endl;
      return 0;
    }
    

    Würde das so klappen?
    Natürlich hab ich das schon probiert - aber so richtig hinbekommen habe ich das nicht.
    Wie dem auch sei, ich freu mich schon mal auf meine von euch aufgezeigten Fehler.
    Bitte auch miese Sachen in der Klasse position bemängeln. Gute Kritik hilft immer.

    Nebenfrage:
    Woher nimmt der Compiler dann eigentlich das cpp oder die kompiliere .o Datei?



  • Einfach den namespace nochmal aufmachen und die klasse/weiteren namespace einfügenm, z.b. so:

    #include <iostream>
    using std::cout;
    
    namespace A
    {
        class XYZ {};
    }
    
    namespace A
    {
        namespace B
        {
            class XYZ {};
        }
    }
    
    namespace B
    {
        namespace A
        {
            class XYZ { void someWork(); }; // "nicht schön, aber selten"
        }
    }
    
    void B::A::XYZ::someWork()
    {
        cout << "Ich bin dein Vater, Luke!\n";
    }
    
    int main()
    {
        A::XYZ xyzA;
        A::B::XYZ xyzAB;
        B::A::XYZ xyzBA;
    
     return 0;
    }
    

    Warum eigentlich nicht __POSITION_H__?

    Weil namen mit einem doppel-underline am anfang oder ende dem compiler vorenthalten sind. wirf dazu auch nochmal einen blick ins C++ FAQ.
    [edit]
    Unterstriche "_" in Namen und die Probleme die sie verursachen
    [/edit]

    typedef struct pos pos;

    braucht man in c++ nicht mehr unbedingt.

    Nebenfrage:
    Woher nimmt der Compiler dann eigentlich das cpp oder die kompiliere .o Datei?

    Öhm...bitte? 😕

    mfg



  • Danke, jetzt weiß ich schon mal, wie ich dass dann im Code schreiben muss.

    Wie verbinde ich nun aber die Namespaces im Code mit der Verzeichnisstruktur?
    Wie kann ich in "hui.cpp" position.h inkludieren ohne über direkte Pfadangabe?

    Ich würde es gerne so machen:

    #include "util/position/position.h"
    using namespace util::position;
    int main()
    {
      position myPos(3,4);
       // some stuff
      return 0;
    }
    


  • hehejo schrieb:

    Wie verbinde ich nun aber die Namespaces im Code mit der Verzeichnisstruktur?
    Wie kann ich in "hui.cpp" position.h inkludieren ohne über direkte Pfadangabe?

    Du sagst deinem Compiler, in welchen Verzeichnissen er nach Dateien suchen soll.



  • Shade Of Mine schrieb:

    Du sagst deinem Compiler, in welchen Verzeichnissen er nach Dateien suchen soll.

    Aber wie muss ich es dann in den einzelenen Quellcodedateien schreiben?

    Wie ich es dem Compiler (in meinem Fall gcc/g++) sage wird hoffentlich nicht zu schwer sein..



  • du meinst wie man in übergeordnete verzeichnisse kommt?

    mit "../"

    z.b von hui.cpp nach position.h:

    #include "../../../util/position/position.h"
    

    mfg



  • (PROGRAMM\_SOURCE\_CODE) in diesem verzeichniss würde ich ein verzeichniss names "Include" anlegen das include verzeichniss sollte dann wie im hauptverzeichnis auschaun.dorthin kopierst du nur alle header die notwendig die einzelen cpp und ev lib(a) zu verbinden. und beim gcc oder g++ gibst du dann als zusätzliche anweisung -I(PROGRAMM_SOURCE_CODE)/Include dazu

    alles klar !?
    mfg

    //Bsp aufruf einer header
    #include <util/position/position.h> // das geht am jeden punkt des sources überall gleihc!!
    


  • Ich freu mich!
    Das wird demnächst gleich mal getestet!

    DANKE!



  • Also das Kompilieren funktioniert prächtig.

    Nur der Linker meckert noch noch. Kompiliert wird das Ganze:

    [test] echo $JO_INCLUDE 
    /home/jo/codes/c++/include
    [test] g++ -c hui.cpp -I $JO_INCLUDE 
    [test] g++ -o hui hui.o 
    hui.o(.text+0x134): In function `main':
    : undefined reference to `util::position::position::position(int, int)'
    hui.o(.text+0x146): In function `main':
    : undefined reference to `util::position::position::getPosition() const'
    hui.o(.text+0x198): In function `main':
    : undefined reference to `util::position::position::~position()'
    hui.o(.text+0x1b2): In function `main':
    : undefined reference to `util::position::position::~position()'
    collect2: ld gab 1 als Ende-Status zurück
    [test]
    

    Das heißt doch, dass er die Sachen zwar kompilieren konnte, aber dass er sie zum Linken nicht gefunden hat?
    😕

    hier der Ausschnitt aus meinem Verzeichnis:

    /home/jo/codes/c++/
    |-- fun
    |   `-- test
    |       |-- hui.cpp
    |       `-- hui.o
    |-- include
    |   |-- fun
    |   |   |-- alcatraz
    |   |   |   |-- alcatraz
    |   |   |   |-- alcatraz.h
    |   |   |   |-- ausgabe.txt
    |   |   |   `-- makefile
    |   |   `-- test
    |   |       `-- threadtest
    |   `-- util
    |       `-- position
    |           |-- position.h
    |           `-- position.o
    `-- util
        `-- position
            |-- position.cpp
            |-- position.h
            `-- position.o
    


  • Könnte sich bitte jemand meinen Linkfehler (ein Post höher) ansehen?

    Ich habe keine Ahnung, warum der ld die passenden Dateien nicht findet.
    Der g++ konnte ja ohne Probleme kompilieren...



  • mh..

    util::position::position::func(...)

    ist da jetzt nicht ein "position::" zuviel reingerutscht?



  • borg schrieb:

    util::position::position::func(...)

    ist da jetzt nicht ein "position::" zuviel reingerutscht?

    Eigentlich nicht.
    namespace und klasse:
    util::position::position::func(...)

    Wenn ein "position::" zuviel drinnen wäre, dann hätte ich es nicht kompilieren können (, oder?).



  • namespace und klasse dürfen nicht gelich heissen (nichts darf gleich heissen!!!)



  • Ok, das wusste ich nicht..
    Ist aber auch schade, da muss man sich wieder gedanken um Namen machen... 🙂

    Aber das hilft leider nichts.
    Ich hab das nun mal geändert. Die Klasse position ist nun direkt im namespace util drin.
    Und alles was damit zusammenhängt abgeändert (Pfade und Einträge in Dateien).

    //position.h 
    #ifndef POSITION_H__
    #define POSTTION_H__
    namespace util
    {
      struct pos
      {
        int pos1;
        int pos2;
      };
      typedef struct pos pos;
    
      class position
      {
      public:
        position(int, int);
        position(const struct pos&);
        position();
        virtual  ~position();
    
        pos getPosition() const ;
        void getPosition(int*, int*) const;
    
      //    void setPosition(int&, int&);
      //    void setPosition(const pos&);
    
      //    void setPositionDelta(int&, int&);
    
      private:
        int m_npos1;
        int m_npos2;
      };
    }
    #endif
    
    //position.cpp
    #include "position.h"
    
    using namespace util;
    
    position::position()
    {
      position::position(0,0);
    }
    
    position::position(int a, int b)
    {
      m_npos1 = a;
      m_npos2 = b;
    }
    
    position::position(const pos& a)
    {
      position(a.pos1, a.pos2);
    }
    
    position::~position() {}
    
    void position::getPosition(int* a, int* b) const
    {
      if(!a || !b)
        return;
    
      *a = m_npos1;
      *b = m_npos2;
    }
    
    pos position::getPosition() const
    {
      pos posi;
      posi.pos1 = m_npos1;
      posi.pos2 = m_npos2;
      return posi;
    }
    
    // hui.cpp
    #include <util/position.h>
    #include <iostream>
    
    using util::position;
    using util::pos;
    
    int main()
    {
        position Pos(7,8);
        pos __POSI = Pos.getPosition();
    
        std::cout << __POSI.pos1 << " " << __POSI.pos2 << std::endl;
        return 0;
    }
    

    Die Dateien position.h und position.o habe ich natürlich in mein angepasstes include Verzeichnis kopiert.

    Der Code wird immer fehlerfrei kompiliert...
    ..dennoch bekomme ich diese Aussgabe:

    [test] g++ -c hui.cpp -I $JO_INCLUDE 
    [test] g++ -o hui hui.o
    hui.o(.text+0x134): In function `main':
    : undefined reference to `util::position::position(int, int)'
    hui.o(.text+0x146): In function `main':
    : undefined reference to `util::position::getPosition() const'
    hui.o(.text+0x198): In function `main':
    : undefined reference to `util::position::~position()'
    hui.o(.text+0x1b2): In function `main':
    : undefined reference to `util::position::~position()'
    collect2: ld gab 1 als Ende-Status zurück
    

    An was kann das liegen?



  • mach
    g++ *.c -o programm
    nich -c verwenden ausser du weisst was du tust



  • Na ich dachte, mit
    g++ -c bla.cpp
    kompiliere ich mir das zu einer .o .
    Und am Schluß kann ich die dann alle per
    g++ *.o -o programm
    kompilieren..

    Und nur g++ *.cpp -o hui -I $JO_INCLUDE langt auch nicht..

    [test] g++ *.cpp -o hui -I $JO_INCLUDE 
    /tmp/ccFlz0sn.o(.text+0x134): In function `main':
    : undefined reference to `util::position::position(int, int)'
    /tmp/ccFlz0sn.o(.text+0x146): In function `main':
    : undefined reference to `util::position::getPosition() const'
    /tmp/ccFlz0sn.o(.text+0x198): In function `main':
    : undefined reference to `util::position::~position()'
    /tmp/ccFlz0sn.o(.text+0x1b2): In function `main':
    : undefined reference to `util::position::~position()'
    collect2: ld gab 1 als Ende-Status zurück
    

    Ich bin ratlos.



  • Wenn ich die "position.o" direkt angebe, dann wird es gelinkt und funktioniert.

    g++ hui.cpp -o hui -I $JO_INCLUDE $JO_INCLUDE/util/position.o
    

    Jetzt werde ich mal schauen, ob ich da nicht einen Parameter finde, dass der g++ die Libs/*.o aus dem $JO_INCLUDE suchen soll.



  • hehejo schrieb:

    Na ich dachte, mit
    g++ -c bla.cpp
    kompiliere ich mir das zu einer .o .
    Und am Schluß kann ich die dann alle per
    g++ *.o -o programm
    kompilieren..

    Object datein tut man nicht zusammen kompilieren sonder verlinken
    verwende das programm "ld"(ist bei den binutils dabei!!
    und ich bleib weiter dabei das g++ ohne "-c" eine exetuable im format a.out macht(linux)

    mfg



  • 😕

    Also ich weiß etz im Moment nicht weiter.
    Die Ausgabedatei ist mir egal. Ob nun a.out oder hui...

    Der g++ findet dank -I $JO_INCLUDE zwar die Datei <util/position.h> aber leider nicht die dazugehörige "position.o", die er in der Linkerphase braucht um alles ordentlich zu linken.

    Wenn ich die position.o mit angebe, dann funktioniert das Linken ja ohne Probleme.

    Leider ist die manpage zum gcc recht groß.
    Darum werde ich wohl etwas länger suchen müssen, bis ich raus habe, welchen Schalter er (gcc) noch braucht, damit er die position.o findet.

    -lposition.o hat nichts gebracht.



  • g++ -c src.cpp 
    g++ src.o -o src.exe
    

    der g++ ruft dann automatisch ld auf.

    Wie kann man eigentlich projekte mit mehreren dateien miteinander kompilieren, ohne den weg über objectfiles? direkt kompilieren führt immer zu undefined references. habe ich da etwa elementare grundkonzepte missverstanden? O_o

    mfg


Log in to reply