Eigenartiger Fehler...



  • Ohne euch jetzt mal den Quellcode zu zeigen bekomme ich folgende Fehlermelung.
    (nicht wundern, XML Parser Quellcode ist aus der nature Application geklaut, aber umgeproggt)

    1>XMLParser.obj : error LNK2005: "public: __thiscall nhe::NamedObject::NamedObject(wchar_t const *)" (??0NamedObject@nhe@@QAE@PB_W@Z) ist bereits in IOXMLObject.obj definiert.
    1>XMLParser.obj : error LNK2005: "public: __thiscall nhe::NamedObject::NamedObject(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (??0NamedObject@nhe@@QAE@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z) ist bereits in IOXMLObject.obj definiert.
    1>XMLParser.obj : error LNK2005: "public: __thiscall nhe::NamedObject::NamedObject(class nhe::NamedObject const &)" (??0NamedObject@nhe@@QAE@ABV01@@Z) ist bereits in IOXMLObject.obj definiert.
    1>XMLParser.obj : error LNK2005: "public: __thiscall nhe::NamedObject::~NamedObject(void)" (??1NamedObject@nhe@@QAE@XZ) ist bereits in IOXMLObject.obj definiert.
    1>XMLParser.obj : error LNK2005: "public: class nhe::NamedObject & __thiscall nhe::NamedObject::operator=(class nhe::NamedObject const &)" (??4NamedObject@nhe@@QAEAAV01@ABV01@@Z) ist bereits in IOXMLObject.obj definiert.
    1>XMLParser.obj : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const & __thiscall nhe::NamedObject::getName(void)const " (?getName@NamedObject@nhe@@QBEABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ) ist bereits in IOXMLObject.obj definiert.
    1>main.obj : error LNK2005: "public: __thiscall nhe::NamedObject::NamedObject(wchar_t const *)" (??0NamedObject@nhe@@QAE@PB_W@Z) ist bereits in IOXMLObject.obj definiert.
    1>main.obj : error LNK2005: "public: __thiscall nhe::NamedObject::NamedObject(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (??0NamedObject@nhe@@QAE@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z) ist bereits in IOXMLObject.obj definiert.
    1>main.obj : error LNK2005: "public: __thiscall nhe::NamedObject::NamedObject(class nhe::NamedObject const &)" (??0NamedObject@nhe@@QAE@ABV01@@Z) ist bereits in IOXMLObject.obj definiert.
    1>main.obj : error LNK2005: "public: __thiscall nhe::NamedObject::~NamedObject(void)" (??1NamedObject@nhe@@QAE@XZ) ist bereits in IOXMLObject.obj definiert.
    1>main.obj : error LNK2005: "public: class nhe::NamedObject & __thiscall nhe::NamedObject::operator=(class nhe::NamedObject const &)" (??4NamedObject@nhe@@QAEAAV01@ABV01@@Z) ist bereits in IOXMLObject.obj definiert.
    1>main.obj : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const & __thiscall nhe::NamedObject::getName(void)const " (?getName@NamedObject@nhe@@QBEABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ) ist bereits in IOXMLObject.obj definiert.
    1>I:\Night Hawk\Night Hawk Engine\Debug\Night Hawk Engine.exe : fatal error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden.
    

    Ich nutze aber ÜBERALL die nötigen Includeguards. Welche Gründe können solche Fehlermeldungen noch haben?



  • Includeguards helfen gegen mehrfache Deklarationen innerhalb einer Übersetzungseinheit, nicht gegen in mehreren Übersetzungseinheiten vorkommende Definitionen.



  • Das heißt für mich?



  • Definitionen in Headern entweder inline kennzeichnen oder in Implementationsdateien auslagern...



  • Hi,
    Machs so:

    Prototypes.h

    #ifndef _PROTOTYPES_H_
    #define _PROTOTYPES_H_
    
    int GetIrgwas(void);
    int GetNochwas(void);
    int Berechne(int a, int b);
    
    #endif /* _PROTOTYPES_H_ */
    

    Definitions.cpp

    int GetIrgwas(void)
    {
       return (45);
    }
    
    int GetNochwas(void)
    {
       return (2345);
    }
    int Berechne(int a, int b)
    {
       return (a+b);
    }
    

    Alle Quellcodedateien, die eine Funktion verwenden, inkludieren lediglich 'Prototypes.h'.
    Damit sollte es funktionieren 😉 .
    Hoffe das war verständlich.



  • Sorry, ich habe nicht ganz verstanden, was du meinst.

    Also, wenn ich in der C++ Datei, in der die Klasen und Members deklariert sind, die include des dazugehörigen Headers entferne, bekomme ich fehler(bla bla bla nicht deklariert)



  • Hier mal die Klasse:

    #if !defined(__nhe_NamedObject_hpp__)
    #define __nhe_NamedObject_hpp__
    
    #include "../StdTypes.hpp"
    
    namespace nhe
    {
    
    class NamedObject
    {
    protected:
    	wString name_;
    
    public:
    	NamedObject(const nhwChar* name = nhNULL);
    	NamedObject(const wString& name);
    	NamedObject(const NamedObject&  other);
    
    	~NamedObject(nhVoid);
    
    	NamedObject& operator =(const NamedObject& other);
    
    	inline nhVoid setName(const nhwChar* name);
    	inline nhVoid setName(const wString& name);
    
    	const wString& getName(nhVoid) const;
    };
    
    NamedObject::NamedObject(const nhwChar* name /* = nhNULL */)
    {
    	name_ = name;
    }
    
    NamedObject::NamedObject(const wString& name)
    {
    	name_ = name;
    }
    
    NamedObject::NamedObject(const NamedObject& other)
    {
    	if(this != &other)
    		name_ = other.name_;
    }
    
    NamedObject::~NamedObject(nhVoid)
    {
    
    }
    
    NamedObject& NamedObject::operator =(const NamedObject& other)
    {
    	if(this != &other)
    		name_ = other.name_;
    
    	return(*this);
    }
    
    inline nhVoid NamedObject::setName(const nhwChar* name)
    {
    	name_ = name;
    }
    
    inline nhVoid NamedObject::setName(const wString& name)
    {
    	name_ = name;
    }
    
    const wString& NamedObject::getName(nhVoid) const
    {
    	return(name_);
    }
    
    }
    
    #endif
    


  • Geht's was genauer?

    Du musst Methoden, die Du deklarierst, entweder in einer .cpp Datei definieren, oder im Header als inline markieren, damit sie in der Linkage nicht mehrfach vorkommen...

    // A.hpp
    class A {
    void X();
    };
    
    void A::X() {
    } // blöd, besser in einer .cpp definieren
    


  • Tc++H schrieb:

    Sorry, ich habe nicht ganz verstanden, was du meinst.

    Nit schlimm 😉 ...Also:

    Tc++H schrieb:

    [...]die include des dazugehörigen Headers entferne, bekomme ich fehler(bla bla bla nicht deklariert)

    Hm ich würde daraus und aus der geposteten Error-Log mal schließen, du hast alles in Headern gemacht...das ist...emmm kagge^^

    Ok ich schreib dir nochmal n Beispiel mit Klassen:

    CDemo.h

    class CDemo
    {
       private:
         int _iData;
       public:
         CDemo(void);
         ~CDemo(void);
    
         int getData(void);
         void setData(int iNew);
    }
    

    CDemo.cpp

    #include "CDemo.h"
    
    CDemo::CDemo(void)
    {
    }
    
    CDemo::~CDemo(void)
    {
    }
    
    int CDemo::getData(void)
    {
       return (this->_iData);
    }
    
    void CDemo::setData(int iNew)
    {
       this->_iData = iNew;
    }
    

    Hier ist's wieder genau so: Immer wenn du eine Quellcodedatei (*.cpp) hast, die die Klasse
    CDemo benötigt, inkludierst du einfach CDemo.h. 👍



  • Danke, nochmal, Ich haber es jetzt so gemacht und der Fehler ist weg!!!

    warum ist der Fehler sonst noch nie aufgetreten? Ich habe sonst oft alles im header definiert.



  • Tc++H schrieb:

    Danke, nochmal, Ich haber es jetzt so gemacht und der Fehler ist weg!!!

    Wie 'so' ?

    Tc++H schrieb:

    warum ist der Fehler sonst noch nie aufgetreten? Ich habe sonst oft alles im header definiert.

    Dann haste wohl vorher die Defs in einem header nicht in mehreren *.cpp Dateien inkludiert.



  • Noch eine kleine Frage: Kann es sein, dass der ganze Spaß bei templates nicht mehr Funktioniert? den wenn ich meine Singletonklasse auslagere, bekomme ich wieder stress:

    #if !defined(__nhe_Singleton_hpp__)
    #define __nhe_Singleton_hpp__
    
    #include "../StdTypes.hpp"
    
    namespace nhe
    {
    
    template<class T_>
    class Singleton
    {
    private:
    		// copy constructor
    	Singleton(const Singleton& other);
    		// assignment operator
    	Singleton& operator =(const Singleton& other);
    
    protected:
    		// constructor
    	Singleton(nhVoid);
    		// destructor
    	virtual& ~Singleton(nhVoid);
    
    public:
    	 static T_& getInstance(nhVoid);
    };
    
    //-------------------------------------------------------------------------//
    //
    //-------------------------------------------------------------------------//
    template<class T_> 
    Singleton<T_>::Singleton(nhVoid)
    {
    
    }
    
    //-------------------------------------------------------------------------//
    //
    //-------------------------------------------------------------------------//
    template<class T_> 
    Singleton<T_>::~Singleton(nhVoid)
    {
    
    }
    
    //-------------------------------------------------------------------------//
    //
    //-------------------------------------------------------------------------//
    template<class T_> 
    T_& Singleton<T_>::getInstance(nhVoid)
    {
    	static T_ instance_;
    
    	return(instance_);
    }
    
    }
    
    #endif
    

    Ich hatte probiert, das Ding mit in eine *.cpp zu packen.



  • siehe FAQ


Anmelden zum Antworten