Objekt in einer Headerdatei erstellen



  • Hallo,
    man kann ja bei einer Klasse nach den geschweiften Klammern vor dem Semikolon bereits Objekte erstellen.
    Wenn dies in der gleichen Datei geschieht, in der sich auch die main()-Funktion befindet, klappt das auch ohne Probleme und das Objekt lässt sich verwenden.
    Wenn man das jedoch in einer eigenen Headerdatei versucht, dann bekommt man folgende Fehler:

    Fehler LNK2005 "class Hangman game" (?game@@3VHangman@@A) ist bereits in Hangman.obj definiert.

    Fehler LNK1169 Mindestens ein mehrfach definiertes Symbol gefunden.

    Meine Frage ist, ob das schlicht nicht geht und man ein Objekt nur mit dem Klassennamen in einer Funktion definieren kann oder ob ich etwas übersehen habe.



  • Du inkludierst die Hangman.h Datei vermutlich in mehr als einer C++ Datei. Bei jedem Inkludieren versucht der Compiler die Variable game anzulegen. Spätestens beim 2. Mal geht das dann schief, weil sie schon aus dem 1. Durchlauf existiert.

    Lektion 1:
    Globale Variablen sind böse.



  • Wenn ich dich richtig verstanden habe, möchtest du in einer .h-Datei folgendes haben:

    struct Hangman {
        int some_variables;
    } game;
    

    Das geht schon, ist aber eine sehr schlechte Idee.
    Denn das bedeutet, dass jede Übersetzungseinheit, die den Header includet, diese Variable erzeugt. Insgesamt darfst du die Variable im ganzen Programm aber nur einmal haben. Also musst du nun immer alle Dateien des Projektes, die irgendwie diesen Header includen, auf einmal kompilieren. Du kannst nicht mehr separat kompilieren.

    Deine Fehlermeldung ist auch eine Linkerfehlermeldung, keine Compilerfehlermeldung. Du hast also in der Übersetzungseinheit "Hangman.obj" schon diese Variable drin. Du darfst nun diesen Header nirgends sonst verwenden.

    Du könntest diese Variable im Header als extern markieren und dann in einer cpp-Datei erzeugen. Das ginge. Die Frage aber ist, ob du so eine globale Variable wirklich benötigst (ich bin mir sehr sicher: du brauchst sie nicht). Vermeide also einfach dieses Pattern. Erzeuge die Variable "game" erst im main .



  • Dass globale Variablen zu vermeiden (was ja eigentlich immer möglich ist) sind, weiß ich schon. Irgendwie habe ich das aber nicht als globale Variable erkannt, mein Fehler.
    Und ja, das mit dem zweimal inkludieren wird wohl der Fehler sein (einmal die Datei mit der Klassendefinition und einmal eine andere Klasse).

    Danke euch beiden, das ging ja schnell, 😉


  • Mod

    Genau genommen hat der Compiler sogar jedes Mal Erfolg, und erzeugt Code für die Variable. Wenn der Compiler dann fertig ist, guckt der Linker auf den Code und sieht X-Mal Code für die Variable game und beschwert sich, weil er nicht mehr weiß, welche davon nun gemeint ist, wenn man von game spricht.

    Die Lektion ist natürlich die gleiche: Keine¹ Definitionen in Headern (das beinhaltet auch Funktionen!) machen. Und am besten auch allgemein keine globalen Zustände im Programm haben.

    ¹: Außer natürlich man hat einen von den Fällen, in denen es doch erlaubt ist und sogar verpflichtend ist. C++ ist eben nicht so ganz einfach 😃


Anmelden zum Antworten