[SOLVED] Error LNK1120: 1 nicht aufgelöste Externe und Verweis auf nicht aufgelöstes externes Symbol



  • Hallo Leute,

    ich habe angefangen mit SDL ein Framework für Spiele zu schreiben. Ich habe dort eine Game Klasse gemacht, mit einem privaten Konstruktor und einer statischen Instanz der Klasse Game, sowie einer Funktion, mit der ich auf die statische Instanz zugreifen kann. Die Game Klasse ist also ein Singleton.

    // --- Game.h ---
    
    // general structure of the game 
    
    #ifndef __Game__
    #define __Game__
    
    #include "Color.h"
    #include "GameObject.h"
    #include "Object.h"
    #include "Player.h"
    #include "SizeHandler.h"
    #include "Standard.h"
    #include "Texture.h"
    #include "Vector2D.h"
    #include "LoaderParams.h"
    
    class Game
    {
    	private:
    
    		// private constructor
    
    		Game();
    
    		// static game instance
    
    		static Game* sInstance;	
    
    	public:		
    
    		// -- static instance function --
    
    		static Game* Instance()
    		{
    			if (sInstance == 0)
    			{
    				sInstance = new Game();
    
    				return sInstance;
    			}
    
    			return sInstance;
    		}		
    };
    
    #endif __Game__
    

    Hier die Implementierung in der .cpp-Datei:

    // --- Game.cpp ---
    
    // class Game
    
    #include "Game.h"
    
    // initialize static Game instance
    
    Game* Game::sInstance = 0;
    
    // Initialize, Event, Update, Draw, Clean ...
    

    Ich habe da eigentlich noch eine Game-Loop programmiert, die ich jetzt aber aus dem Code rausgenommen hab, weil der Quellcode sonst zu unübersichtlich wäre, denke ich. Da wäre halt noch eine Initialize() Funktion und dann die Loop aus Event(), Update() und Draw() und zum Schluss noch eine Clean() Methode.

    Wie man an den vielen #include Anweisungen erkennt habe ich auch Klassen für Texturen und Objekte programmiert, für Vektoren und für das Handling von Parametern, usw. Game-Objekte habe ich in einer polymorphen Vererbung geregelt, in der eine abstrakte Basisklasse die Struktur der abgeleiteten Klassen festlegt.

    Ich weiß nicht, ob noch mehr Code notwendig ist. Jedenfalls sagt mir der Compiler folgendes:

    Fehler 3 error LNK1120: 1 nicht aufgelöste Externe C:\Users\Ivan\Documents\Visual Studio 2012\Projects\C++\SDL\RoleJump\Debug\RoleJump.exe RoleJump

    Fehler 2 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""private: __thiscall Game::Game(void)" (??0Game@@AAE@XZ)" in Funktion ""public: static class Game * __cdecl Game::Instance(void)" (?Instance@Game@@SAPAV1@XZ)". C:\Users\Ivan\Documents\Visual Studio 2012\Projects\C++\SDL\RoleJump\RoleJump\main.obj RoleJump

    Warnung 1 warning LNK4098: Standardbibliothek "msvcrt.lib" steht in Konflikt mit anderen Bibliotheken; /NODEFAULTLIB:Bibliothek verwenden. C:\Users\Ivan\Documents\Visual Studio 2012\Projects\C++\SDL\RoleJump\RoleJump\MSVCRTD.lib(cinitexe.obj) RoleJump

    Das Problem scheint mit dem Konstruktor der Game Klasse zusammenzuhängen und mit der statischen Instant static Game* sInstance.

    Ich weiß nicht, was das heißt und bin aus vielen anderen Beiträgen zu diesem Fehler nicht schlau geworden. Vielleicht kann mit hier ja jemand helfen.



  • Deine Klasse hat jetzt gar keinen Konstruktor. Dann kannst du auch kein Game Objekt erstellen.



  • Game* Game::sInstance = 0;
    

    Was solln das darstellen? Definiert wurde die Variable bereits in der headerdatei und auf Private Variablen kannst du ohnehin nicht von außen zugreifen.



  • tkausl schrieb:

    Game* Game::sInstance = 0;
    

    Was solln das darstellen?

    Eine Definition.



  • Ich will die statische Instanz sInstance gleich Null setzen, und mit der Funktion Game::Instance() kann ich dann auf diese zugreifen oder nicht?

    In der main.cpp habe ich folgendes programmiert:

    Game::Instance()->Initialize(...);
    
    while(running)
    {
       Game::Instance()->Update();
       (...)
    }
    (...)
    


  • tkausl schrieb:

    Game* Game::sInstance = 0;
    

    Was solln das darstellen? Definiert wurde die Variable bereits in der headerdatei und auf Private Variablen kannst du ohnehin nicht von außen zugreifen.

    Ohh stimmt, wie mach ich denn den Singleton der Game Klasse richtig?



  • out schrieb:

    Deine Klasse hat jetzt gar keinen Konstruktor. Dann kannst du auch kein Game Objekt erstellen.

    Genau das will ich ja auch. Ich möchte nicht, dass man mehrere Game Instanzen erstellen kann. Es soll halt nur eine Instanz geben, nur ein Game. Und auf dieses statische Objekt will ich über die Methode Game::Instance() zugreifen können. Die Methode gibt mir ja die statische Instanz als Rückgabewert zurück, damit ich darauf zugreifen kann.



  • huzzm schrieb:

    tkausl schrieb:

    Game* Game::sInstance = 0;
    

    Was solln das darstellen? Definiert wurde die Variable bereits in der headerdatei und auf Private Variablen kannst du ohnehin nicht von außen zugreifen.

    Ohh stimmt, wie mach ich denn den Singleton der Game Klasse richtig?

    Nix da "stimmt", du machst das genau richtig. Jedenfalls soweit es den Einwand von tkausl angeht, ansonsten kann man über Singletons im Allgemeinen und diese Umsetzung im Besonderen natürlich diskutieren.

    Auf deine ursprüngliche Frage: Der Konstruktor ist nicht implementiert. Du erzeugst in Instance ein Objekt der Klasse, dafür wird der benötigt.



  • Bashar schrieb:

    huzzm schrieb:

    tkausl schrieb:

    Game* Game::sInstance = 0;
    

    Was solln das darstellen? Definiert wurde die Variable bereits in der headerdatei und auf Private Variablen kannst du ohnehin nicht von außen zugreifen.

    Ohh stimmt, wie mach ich denn den Singleton der Game Klasse richtig?

    Nix da "stimmt", du machst das genau richtig. Jedenfalls soweit es den Einwand von tkausl angeht, ansonsten kann man über Singletons im Allgemeinen und diese Umsetzung im Besonderen natürlich diskutieren.

    Auf deine ursprüngliche Frage: Der Konstruktor ist nicht implementiert. Du erzeugst in Instance ein Objekt der Klasse, dafür wird der benötigt.

    Ich hab den Konstruktor ja nur auf private gesetzt, also kann die Methode Instance() ja auf den Konstruktor zugreifen oder? Muss ich etwas Bestimmtes mit dem Konstruktor machen?



  • huzzm schrieb:

    Muss ich etwas Bestimmtes mit dem Konstruktor machen?

    Du musst ihn definieren. Implementieren. Sowas hinschreiben:

    Game::Game() 
    {
      // initialize stuff
    }
    


  • Bashar schrieb:

    huzzm schrieb:

    Muss ich etwas Bestimmtes mit dem Konstruktor machen?

    Du musst ihn definieren. Implementieren. Sowas hinschreiben:

    Game::Game() 
    {
      // initialize stuff
    }
    

    Stimmt, danke. Ich habe jetzt folgendes mal exemplarisch implementiert:

    Game::Game()
    {
       cout << "hallo" << endl;
    }
    

    Dann erhalte ich aber folgende Fehlermeldung, die ich einfach mal überhaupt nicht raffe:

    Fehler 1 error C2512: 'Texture': Kein geeigneter Standardkonstruktor verfügbar c:\users\ivan\documents\visual studio 2012\projects\c++\sdl\rolejump\rolejump\game.cpp 19 1 RoleJump

    Wieseo plötzlich die Texture Klasse?



  • Das kann man aus dem bisher geposteten Code nicht beantworten. Es kann auch normalerweise nicht sein, dass der Fehler nach dieser Änderung aufgetreten ist, weil das vorher ein Linkerfehler war und jetzt ein Compilerfehler ist.



  • Bashar schrieb:

    Das kann man aus dem bisher geposteten Code nicht beantworten. Es kann auch normalerweise nicht sein, dass der Fehler nach dieser Änderung aufgetreten ist, weil das vorher ein Linkerfehler war und jetzt ein Compilerfehler ist.

    Dann trotzdem danke schonmal für deine hilfreichen Antworten 🙂


Log in to reply