header / cpp



  • Nein, den Compiler hab ich auch. Aber foo.cpp wird wegen der #ifndef -Direktive in der .cpp-Datei gar nicht mehr eingebunden.

    Aber wieso machst du das so umständlich? Auf folgende Weise ginge es viel einfacher, dann könntest du dir auch die Abfragen wegen doppelter Inkludierung sparen. Ausserdem verwechselst du Deklarationen mit Definitionen.

    Header:

    class foo
    {
       foo(); // Das sind DEKLARATIONEN!
    };
    

    CPP-Datei:

    #include "foo.h"
    foo::foo() // Das sind DEFINITIONEN!
    {
    }      // KEIN SEMIKOLON!!!
    
    int main()
    {
    }
    


  • hab mich bei den definitionen und deklarationen nur verschrieben, habs ja auch gleich korrigert.
    warum sind die semikolon denn da falsch? funktioniert doch auch.
    naja die #ifndef sachen hab ich ja drin falls ich indirekt zweimal den gleichen header einbinde und der dann nicht rummeckert, das er den schon kennt.



  • FreakyBKA schrieb:

    warum sind die semikolon denn da falsch? funktioniert doch auch.

    Natürlich funktioniert es, das Semikolon ist jedoch überflüssig. Man nennt ein einziges ; eine Leeranweisung, da es nichts bewirkt. Und in C++ muss am Ende eines Blockes kein Semikolon geschrieben werden (ausser bei Klassen, da diese Datentypen sind).

    FreakyBKA schrieb:

    naja die #ifndef sachen hab ich ja drin falls ich indirekt zweimal den gleichen header einbinde und der dann nicht rummeckert, das er den schon kennt.

    Das ist ja schön und gut, aber deswegen brauchst du trotzdem nicht im Header die CPP-Datei einzubinden.



  • FreakyBKA schrieb:

    naja die #ifndef sachen hab ich ja drin falls ich indirekt zweimal den gleichen header einbinde und der dann nicht rummeckert, das er den schon kennt.

    Die Includeguards gehören ausschließlich in die Dateien die du inkludierst (Sprich Header). Davon abgesehen ist es üblich Makros (defines) immer groß zu schreiben. Semikolons sind an den von Nexus erwähnten stellen unnötig (und gehören dort auch nicht hin), der Compiler wird dies aber durchgehen lassen.

    Also ganz kurz das Beispiel angepasst:

    // foo.h

    #ifndef FOO_HEADER
    #define FOO_HEADER
    
    class foo
    {
      public:
       foo();
    };
    
    #endif
    

    // foo.cpp

    #include "foo.h"
    
    foo::foo()
    {
    }
    

    // main.cpp

    #include "foo.h"
    
    int main()
    {
      foo f;
    }
    

    cu André



  • dann versteh ich aber nicht woher eine andere datei, in der ich nur die header inkludieren würde, weiß wie die entsprechenden definitionen aussehen. ich mein der sieht doch in seinem code dann nur die deklarationen ohne die definitionen.

    also wenn ich mir irgendwo fooA.h und fooA.cpp definiere und nur fooA.cpp die fooA.h includiert. wenn ich jetzt in fooB.h die fooA.h includieren dann kennt die doch die ganzen definitionen aus fooA.cpp nicht, oder bin ich da jetzt auf dem flaschen dampfer? oder wenn ich in der main.cpp einfach nur fooA.h includiere, ist das ja der ähnliche fall.



  • Makro (defines) schreib ich sonst auch immer groß, hab hier jetzt nur der schnelle halber nicht darauf geachtet.



  • FreakyBKA schrieb:

    also wenn ich mir irgendwo fooA.h und fooA.cpp definiere und nur fooA.cpp die fooA.h includiert.

    Wie oft müssen wir dir noch sagen, dass man keine CPP-Dateien in Header inkludiert?

    Es macht bei einer Klasse nichts, wenn die Definition von deren Memberfunktionen nicht bekannt ist, solange du die Funktionen nicht aufrufst.



  • hab ich doch auch gar nicht geschrieben, dass ich .cpp in .h inkludiere sondern umgedreht.

    main.cpp

    #include "fooA.h" /*deklariert die klasse fooA*/
    
    int main()
    {
      fooA A;
      return 0;
    }
    

    hier versteh ich dann nicht woher die main.cpp weiß wie die fooA-Klasse definiert ist?



  • FreakyBKA schrieb:

    main.cpp

    #include "fooA.h" /*deklariert die klasse fooA*/
    
    int main()
    {
      fooA A;
      return 0;
    }
    

    hier versteh ich dann nicht woher die main.cpp weiß wie die fooA-Klasse definiert ist?

    Ganz einfach: gar nicht!

    Der Compiler benötigt nur eine Deklaration. Die ist in der Headerdatei vorhanden. Der Compiler merkt nun, dass die Definition nicht in der gleichen Quelldatei ist und markiert das in der erzeugten Objektdatei entsprechend.

    Im zweiten Schritt kommt der Linker (dieser benötigt die Definitionen) und ersetzt diese Markierungen durch Verweise auf den aus einer anderen Quelldatei erstellten Funktionen.



  • *schnipp*

    Da hatte es 2 Seiten.. 🙄



  • Ups sorry, da hab ich nicht genau gelesen 😉

    Um mal die beiden vorherigen Beiträge zu ignorieren (:p):

    Wie gesagt, so lange du keine der noch nicht definierten Funktionen aufrufst, geht alles ohne Probleme. Wenn du aber einen neuen Standardkonstruktor schreibst, muss dieser definiert sein, damit du eine Instanz der Klasse erstellen kannst.

    Beim Aufruf nicht-definierter Funktionen erhältst du diesen Linker-Error: error LNK2001: Nicht aufgelöstes externes Symbol ""public: __thiscall ...



  • Beim Aufruf nicht-definierter Funktionen erhältst du diesen Linker-Error: error LNK2001: Nicht aufgelöstes externes Symbol ""public: __thiscall ...

    genau das erhalte ich jetzt, nachdem ich überall die inkludierung der cpp-dateien aus den header-dateien rausgenommen habe 😞

    Im zweiten Schritt kommt der Linker (dieser benötigt die Definitionen) und ersetzt diese Markierungen durch Verweise auf den aus einer anderen Quelldatei erstellten Funktionen.

    woher nimmt er die verweise? er weiß doch gar nicht wo ich die entsprechende .cpp habe.



  • Doch. Dafür werden ja die anderen Source Dateien mitgelinkt.



  • dh ich muss jede einzelne cpp-Datei, die ich irgendwann mal erstellt habe und verwenden will, mit ins projekt aufnehmen? genau das wollte ich eigentlich vermeiden um das projekt übersichtlich zu halten.



  • FreakyBKA schrieb:

    Beim Aufruf nicht-definierter Funktionen erhältst du diesen Linker-Error: error LNK2001: Nicht aufgelöstes externes Symbol ""public: __thiscall ...

    genau das erhalte ich jetzt, nachdem ich überall die inkludierung der cpp-dateien aus den header-dateien rausgenommen habe 😞

    Zeig doch mal deinen aktuellen Code. Das sollte eigentlich nicht passieren. Du hast ja die benötigten Methoden schon definiert, oder?



  • ja ich hab die methoden definiert, allerdings hab ich halt nich die cpp-datei mit im projekt drin. das wollte ich halt der übersicht wegen nicht.



  • FreakyBKA schrieb:

    dh ich muss jede einzelne cpp-Datei, die ich irgendwann mal erstellt habe und verwenden will, mit ins projekt aufnehmen? genau das wollte ich eigentlich vermeiden um das projekt übersichtlich zu halten.

    Du könntest natürlich auch eine Dll aus den Teilen machen, die du sicher brauchst und sicher nicht mehr geänder werden. Dann musst du da nur noch die Header includen , die libs linken und dll in den Ordner kopieren.



  • es halt so das ich mir viele klassen selbst definiert hab und die möchte ich einfach inkludieren können ohne das ich jedesmal extra die cpp-datei mit ins projekt aufnehmen muss, und dachte ich halt ich schreib das einfach in die header-datei mit rein. das hat ja auch prima funktioniert, bis ich jetzt mit Qt arbeite und da noch ein paar andere sachen mit diversen header-files gemacht werden müssen und dann meckert er da rum, das halt alles schon mal irgendwo definiert wurde.



  • wie funktioniert das denn mit den dll/lib erstellen und linken?




Anmelden zum Antworten