namespace templateklasse und typdef



  • Wenn ich doch ein #pragma once oder ifndef Konstrukt in der Header habe wird doch die Variable auch nur einmal initialisiert?



  • Weiß dass keiner? Zu kompliziert erklärt? Ich muss das dringend wissen!!!



  • Nein wird sie nicht! Der Compiler kompiliert jedes cpp-file einzeln, alle Informationen der Header werden dabei durch die includes vom Präprozessor eingebunden. Das heißt dem Compiler liegt zum Schluß ein großes cpp-file vor mit allen Informationen aus dem Header. Mit ifndef und ähnlichen verhinderst du, dass mehrere Texte mehrmals eingebunden werden, Aber nicht das eine andere cpp-file den Header einbindet. Somit kann ein anderes cpp-file auch eine Instanz erstellen. Beim Linken der kompilierten cpp-files, kommt es dann zum Konflikt.



  • Nachtrag:
    Du brauchst dringend ein cpp-file, weil du einen Header allein nicht kompilieren kannst. Die Instanz selber darf aber im Header stehen, solange der Header maximal einmal im Projekt genutzt wird.



  • Du brauchst dringend ein cpp-file, weil du einen Header allein nicht kompilieren kannst.

    Wieso soll ich einen Header nicht alleine kompilieren können? Wenn ich nur Inlinefunktionen habe geht das sehr wohl.



  • In einem anderen Fall habe ich das gleiche schon mal gemacht. Dort allerdings ohne namespace dort funktioniert das einwandfrei nur im Header.



  • Nein,

    inline-Funktionen/Methoden werden dort eingesetzt, wo sie aufgerufen werden.
    Damit stellen sie keine Funktions-Definiton dar. Das gleiche gilt für Templates, von ihnen erstellt der Compiler eine konkrete Instanz, diese darf nur einmal in allen Object-Files vorhanden sein.
    Übrigens mit dem Namespace hat das ganze nix zu tun. Namespace ist nur sowas wie schreibe vor alle Bezeichner im Namespace noch einen Präfix. Ist also zum Schluß ein Name wie jeder andere Ohne Namespace auch.

    P.S. das kompilieren ohne cpp-file macht weder Sinn, noch glaube ich das es alle Kompiler mitmachen.
    P.S.2 Du solltest dir mal die Bedeutung von Headern in C/C++ anschauen



  • Na wenn ich in VisualStudio mit dem Assistenten eine Klasse erstelle und dann Inline anklicke erstellt auch er mir nur ein Header file. Und lässt die .cpp Datei weg.



  • Wie geschrieben solltest du dir mal Gedanken über die Bedeutung von Header-files und cpp-files machen. Dann auch noch mal anschauen was genau eine inline Funktion ist. Unterschiede Deklaration und Definition.
    Die ganzen Grundlagen zur C/C++ Programmierung. Damit sollten sich so einige Fragen klären. Eigentlich sollte so etwas klar sein bevor man mit Templates und Ableitungen etc. konfrontiert wird. Sonst läuft man immer wieder in Fallen und dass wird erst richtig eklig um so komplexer das Projekt wird.



  • Ich weiß nicht was ich mir da anschauen sollte. Headerfiles sind die Definitionen der Klassen oder Funktionen und im .cpp werden sie implementiert. Inline sind Funktionen die direkt in der Deklaration implemetiert werden wenn sie nicht zu groß sind. Und was soll ich da jetzt noch mehr nachschauen.

    Wenn ich nur inline Funktionen in meiner Header habe brauche ich doch kein .cpp File. Also, und wie gesagt VS legt ja auch nur ein Headerfile an wenn man inline auswählt.



  • Sorry,

    aber schau dir die Sachen, die ich dir genannt habe mal an. Wenn du was nicht verstehst frag konkret nach. Aber dir jetzt noch mal das gleiche wie weiter oben als Erklärung zu schreiben wird es auch nicht bringen. Die Bedeutung:
    - Deklaration und Definition
    - was gehört in ein Header-file, was in ein cpp-file ?
    - was genau bedeutet inline ?
    - was macht ein Template ?
    - wie genau wird in c/c++ ein Programm erstellt (Stichwort: Compiler/Linker)
    das ist alles wichtig, und hab ich weiter oben schon mal versucht zu erklären.
    Wenn etwas nicht klar ist fragen! Aber im Netz sollte alles ausführlich erklärt sein und ein gutes Buch die Dinge vor Einführung erklären.



  • Sorry aber ich weiß nicht was du mir sagen willst.

    Ich weiß was inlinefunktionen sind. Aber ich brauch dir das ja hier nicht zu erklären du scheinst es ja auch zu wissen. Aber ich weiß nicht wieso du mir weiß machen willst dass man zu jeder Header auch ein .cpp File braucht.



  • Man braucht auch nicht für jeden Header ein cpp-file, dass ist vielleicht falsch rüber gekommen. Du brauchst aber für jede Definition/Implementation ein cpp-file. Und deine Deklarationen stehen im Header, zumindest wenn du sie von anderen cpp-files benutzen willst. Diese strikte Trennung ist wichtig weil sonst die Symbole in allen cpp-files definiert werden, in dennen der Header eingebunden wird.
    Und ein Header allein kann nicht compilieren, er muß immer irgendwo eingebunden sein.
    Dein Problem ist einfach das mangelnde Verständnis für den Buildprozess. Du solltest dich wirklich einmal mit den Begriffen Präprozessor/compilieren/linken auseinander setzten. Was machen die Programme und was nicht, ohne Verwendung von Templates oder inline-Methoden. Wenn du die Zusammenhänge verstanden hast, wird dir auch klar warum das eine geht und das andere nicht. D.h. die Fehlermeldungen erscheinen auch weniger Bahnhof zu sein.



  • Hier mal ein typisches Makefile um Programme zu erstellen, das gleiche passiert auch in Visual Studio. Kannst du ausprobieren indem du "nmake /f Makefile" im Verzeichnis mit dem Makefile aufrufst (evtl. mußt du dazu die Konsole aus dem Visual Studio Programme Ordner im Startmenü nehmen).
    Ein Makefile funktioniert so: Vor dem Doppelpunkt steht ein Ziel in unserem Fall "Programm.exe", dahinter stehen die Abhängigkeiten des Zieles. In den folgenden Zeilen steht nach einem Tabulator (!Wichtig) die Anweisung zum erstellen des Zieles. Compiler und Linker arbeiten in der Regel so, dass sie alle folgenden Dateien verarbeiten und das Resultat in der Datei hinter -o speichern. Wie du gut erkennen kannst sind im Compiler-Aufruf keine Header (auch nicht im Linker).
    Die Header werden durch den Präprozessor, der durch den Compiler vorher gerufen wird, an die Stellen eingeblendet wo die "#include <blabla>" sind. Durch "#ifndef" verhinderst du nun, dass dies mehrmals geschieht. Nach dem Compilieren sind also alle definierten Symbole in der Objekt-Datei "*.obj" vorhanden. Wenn der Linker nun diese verarbeitet und mehrmals die gleichen Symbole findet, weiß er nicht welches das Richtige ist. Also darfst du kein Objekt-File mit dem gleichen Symbol zum Linken hinzufügen.

    Programm.exe: main.obj foo.obj bar.obj baz.obj
    	Linker main.obj foo.obj bar.obj baz.obj -o Programm.exe
    
    main.obj: main.cpp main.h foo.h bar.h baz.h
    	Compiler main.cpp -o main.obj
    
    foo.obj: foo.cpp foo.h
    	Compiler foo.cpp -o foo.obj
    
    bar.obj: bar.cpp bar.h
    	Compiler bar.cpp -o bar.obj
    
    baz.obj: baz.cpp baz.h
    	Compiler baz.cpp -o baz.obj
    

    Ich hab dir hier übrigens nichts anderes geschrieben als weiter vorne schon einmal!


Anmelden zum Antworten