#include-Problem...



  • Hi Leute, schon wieder ich...;)

    Ich habe die Header-Datei "main_functions.h" wo Klassen deklariert sind und die Methoden dazu auch.Ausserdem habe ich einige enum's und functions da hineingesteckt.Sie includiert <iostream> und <string>.
    Allerdings habe ich ein komisches Problem.
    Ich habe die "main.cpp" und die "menu.cpp".
    Beide inkludieren die main_functions.h und die iostream und string-Header Dateien.Doch ich bekomme andauernd den Fehler wenn ich die main_functions.h inkludiere, dass verschiedene Klassen schon einmal deklariert wurden(was wohl daran liegt, dass sie in der anderen Datei schon inkludiert ist...Aber es müsste doch eigentlich gehen?)
    Ich versteh's wirklich nicht... 😕

    BTW, wenn ich in einer header-Datei iostream.h und andere Bibiliotheken einbinde, muss ich die dann nocheinmal in der *.cpp Datei einbinden?



  • du mußt zu Beginn jeder Headerdatei prüfen, ob diese nicht vielleicht schon mal eingebunden wurde:

    #ifndef NAMEDERHEADERDATEI_H
    #define NAMEDERHEADERDATEI_H
    
        //declarations, enumerations,......
    
    #endif
    


  • Du musst einfach einfach aufpassen, dass eine Datei nicht zweimal includiert wird. Anders geht's nicht. Hier mal ein Tip:

    #ifndef MeinName_H
      #define MeinName_H
    
      //Hier kommt der Ganze Müll rein, den eh kein Mensch braucht...
      //Also Deklarationen, Funktionen und was man sonst braucht
    #endif
    

    So machen's übrigens auch die C++ Standardbibliotheken.

    edit. Da war einer schneller.



  • Sorry, aber ich bin zu doof dafür.Ich habe diese Befehle auch schon öfters gesehen und in anderem Sourcecode mal geschaut und da steht das genau wie Ihr das sagt.Allerdings will das bei mir nicht so recht fuktionieren...Hier mal meine Fehlermeldung:

    --------------------Configuration: Svennimon - Win32 Debug--------------------
    Compiling...
    main.cpp
    menu.cpp
    Linking...
    menu.obj : error LNK2005: "public: char * __thiscall hero::get_name(void)" (?get_name@hero@@QAEPADXZ) already defined in main.obj
    menu.obj : error LNK2005: "public: void __thiscall hero::set_name(char *)" (?set_name@hero@@QAEXPAD@Z) already defined in main.obj
    menu.obj : error LNK2005: "public: int __thiscall hero::get_pokemon_id(void)" (?get_pokemon_id@hero@@QAEHXZ) already defined in main.obj
    menu.obj : error LNK2005: "public: void __thiscall hero::set_pokemon_id(int)" (?set_pokemon_id@hero@@QAEXH@Z) already defined in main.obj
    menu.obj : error LNK2005: "public: __thiscall attacks::attacks(int,char *,int,int,int,int)" (??0attacks@@QAE@HPADHHHH@Z) already defined in main.obj
    menu.obj : error LNK2005: "public: int __thiscall attacks::get_min_dmg(void)" (?get_min_dmg@attacks@@QAEHXZ) already defined in main.obj
    menu.obj : error LNK2005: "public: int __thiscall attacks::get_max_dmg(void)" (?get_max_dmg@attacks@@QAEHXZ) already defined in main.obj
    menu.obj : error LNK2005: "public: int __thiscall attacks::get_type(void)" (?get_type@attacks@@QAEHXZ) already defined in main.obj
    menu.obj : error LNK2005: "public: int __thiscall attacks::get_max_ap(void)" (?get_max_ap@attacks@@QAEHXZ) already defined in main.obj
    menu.obj : error LNK2005: "public: char * __thiscall attacks::get_attack_name(void)" (?get_attack_name@attacks@@QAEPADXZ) already defined in main.obj
    menu.obj : error LNK2005: "int * Typen" (?Typen@@3PAHA) already defined in main.obj
    menu.obj : error LNK2005: "char const * const ausloeser" (?ausloeser@@3PBDB) already defined in main.obj
    Debug/Svennimon.exe : fatal error LNK1169: one or more multiply defined symbols found
    Error executing link.exe.
    
    Svennimon.exe - 13 error(s), 0 warning(s)
    

    Dabei ist alles so wie es seien sollte...Hier mal ein Auszug aus der Header-Datei:

    #ifndef MAIN_FUNCTIONS_H
    #define MAIN_FUNCTIONS_H
    
    //
    // Initialize some vars and classes
    //
    #include <string.h>
    #include <iostream.h>
    const char * ausloeser = "j";
    
    // Pre-Define Functions
    void get_player_name();
    
    //////////////////////////////////
    // Class: Hero
    //////////////////////////////////
    
    class hero
    {
    private:
    	char name[100];
    	int pokemon_id;
    public:
    	char * get_name();
    	void set_name(char * new_name);
    	int get_pokemon_id();
    	void set_pokemon_id(int new_pkmn_id);
    };
    
    	//
    	// Get the name of the character
    	//
    
    	char * hero::get_name()
    	{
    		return name;
    	};
    
    	//
    	// Set the name of the character
    	//
    
    	void hero::set_name(char * new_name)
    	{
    		strcpy(new_name, name);
    	};
    
    	//
    	// Get the ID of a Pokemon
    	//
    
    	int hero::get_pokemon_id()
    	{
    		return pokemon_id;
    	}
    
    	//
    	// Set the ID of the Pokemon
    	//
    	void hero::set_pokemon_id(int new_pkmn_id)
    	{
    		pokemon_id = new_pkmn_id;
    	}
    [...und so weiter]
    #endif
    

    Vielleicht übersehen ja meine C++-blinden Augen ja was, aber ich denke, das ist alles richtig so... 😞



  • Entweder du lässt die Funktionsdefinitionen in der Headerdatei weg oder du machst sie inline.





  • Ich habe mir die Seite durchgelesen und das letzte Beispiel scheint mein Problem zu sein, allerdings weiss ich immernoch nicht, wie ich diese Fehler beheben kann... 😞



  • #ifndef _myHumbleOpinion
    #define _myHumbleOpinion
    /*
    pack doch deine Klasse hero in eine eigene hero.h und die dazugehörigen Methoden und Funktionen in eine eigene hero.cpp. Die hero.h inkludierst du dann in deiner hero.cpp und in deiner main_functions.h
    */
    #endif

    1st edit: wegen guter deutsch



  • Screib einfach vor alle deine Funktionen "inline". Zumindest hab ich es so verstanden.
    Trtzdem interessiert es mich jetzt auch mal, wie man eine nicht inline Funktion sonst in eine Headerdatei auslagern soll?

    edit.: Wieder jemand schneller!



  • Danke, dass hat funktioniert! 😉



  • freshman schrieb:

    pack doch deine Klasse hero in eine eigene hero.h und die dazugehörigen Methoden und Funktionen in eine eigene hero.cpp. Die hero.h inkludierst du dann in deiner hero.cpp und in deiner main_functions.h

    besser.



  • @V 9 1 9 V: Dein Problem ist zwar gelöst, aber generell sollte man sich angewöhnen, in Headerdateien nur das zu inkludieren, was auch wirklich benötigt wird. Soll heissen: Wenn Du in deiner Klassendeklaration (also dem Klassenheader) als Beispiel ostream oder ofstream oder sowas unbedingt benötigst (also eine Methode deiner Klasse beispielsweise als Argument ostream& besitzt), dann inkludiere die <iostream>. Wenn Du sie nicht benötigst, sondern nur im eigentlichen Code der Methode, dann inkludiere sie in der Klassen-cpp-Datei.

    Kleines Beispiel:

    //klasse.h
    #ifndef KLASSE_H
    #define KLASSE_H
    
    class Klasse
    {
        int methode(int Argument);
    };
    
    #endif //ndef KLASSE_H
    

    Hier brauchst Du keine Standardheader, weil dem Compiler alles bekannt ist.
    Trotzdem brauchst aber meinetwegen im Code deiner methode() cout. Dann also so:

    //klasse.cpp
    #include "klasse.h" //brauchst Du ja eh
    #include <iostream>
    
    int Klasse::methode(int Argument)
    {
        std::cout << "Ich bin die Methode von Klasse!";
    }
    

    Hat auch lang gedauert, bis mir das jemand richtig gesagt hat, vielleicht ist es für dich ja früh genug 😉
    PS: Wenn Du in einem Projekt so arbeitest, mehrere eigene Header-Dateien hast und trotzdem diese Fehlermeldungen bekommst hilft nur noch die sogenannte Forward-Declaration. Damit sagst Du dem Compiler einfach, dass es eine Klasse ostream gibt, aber nicht, wie sie definiert ist. Inkludieren musst Du den dazugehörigen Header aber dann immer noch in der cpp-Datei.

    //klasse1.h
    #ifndef KLASSE1_H
    #define KLASSE1_H
    
    class ostream;
    
    class klasse1
    {
        .
        .
        .
    };
    
    #endif //ndef KLASSE1_H
    

    Ich hoffe, ich war eine Hilfe... 🙄



  • Nimda schrieb:

    Trtzdem interessiert es mich jetzt auch mal, wie man eine nicht inline Funktion sonst in eine Headerdatei auslagern soll?

    Das sollst du ja auch nicht machen. Wenn dir das Schlüsselwort inline zu viel ist, dann definiere die Funktion komplett in der Klasse. Trotzdem wird der Compiler das implizit als inline handeln. Ob er dann tatsächlich inlined oder nicht, ist wiederum eine andere Geschichte. Wie auch immer, solange du keine Template Klasse hast, solltest du grundsätzlich die Definition der Funktionen in eine eigene Übersetzungseinheit auslagern.


Anmelden zum Antworten