Thread: Linker errors with static abstract class...

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    Linker errors with static abstract class...

    Hello, I'm trying to do this:

    Code:
    #include "stdafx.h"
    #include "Menu_State.h"
    #include "Play_State.h"
    #include "IO.H"
    
    void Menu_State::handle_events(State_Manager * state_manager)
    {
    	result = IO::instance().get_input();
    	
    	switch(result)
    	{	
    	case 1: // play blackjack
    		state_manager->change_state(Play_State::Instance());
    /*
    		if(players.size() == 0)
    		{
    			initialize_players(2);
    		}
    		pot = new Pot;
    		deck = new Deck;
    		deck->shuffle_deck();
    		players[0].draw(*(deck), 2);
    		players[1].draw(*(deck), 1);
    		return 3;
    	case 2: // quit game
    		return 4;
    	default:// invalid entry
    		std::cout << "Please enter 1 or 2.\n";
    		return 0;
    */
    	}
    }
    I've bolded the error producing line. It's a function that returns a static instance of the Play_State class, it is a singleton.

    Code:
    #ifndef PLAY_STATE_H
    #define PLAY_STATE_H
    #include "Gamestate.h"
    
    class Play_State : public Gamestate
    {
    public:
    	void init();
    	void cleanup();
    
    	void handle_events(State_Manager * state_manager);
    	void update();
    	void print();
    
    	static Play_State * Instance() 
    	{
    		return &play_instance;
    	}
    
    protected:
    	Play_State() {};
    private:
    
    	static Play_State play_instance; 
    };
    #endif
    I've done something similar to this before and never got a linker error, although I've never done this with a derived class before...

    Here is the Gamestate abstract class:

    Code:
    #ifndef GAMESTATE_H
    #define GAMESTATE_H
    #include "State_Manager.h"
    class State_Manager;
    class Gamestate
    {
    public:
    
    	virtual void init() = 0;
    	virtual void cleanup() = 0;
    
    	virtual void update(State_Manager * state_manager) = 0;
    	virtual void print(State_Manager * state_manager) = 0;
    	virtual void handle_events(State_Manager * state_manager) = 0;
    
    	void change_state(State_Manager * state_manager, Gamestate * state);
    
      protected: Gamestate() { }
    };
    #endif
    I'm getting error messages when trying to grab an instance of the Play_State.

    Code:
    ------ Build started: Project: Blackjack, Configuration: Debug Win32 ------
    Compiling...
    Menu_State.cpp
    Generating Code...
    Skipping... (no relevant changes detected)
    Play_State.cpp
    Linking...
    Menu_State.obj : error LNK2001: unresolved external symbol "private: static class Play_State Play_State::play_instance" (?play_instance@Play_State@@0V1@A)
    C:\Documents and Settings\jcoleman\Desktop\Blackjack\Debug\Blackjack.exe : fatal error LNK1120: 1 unresolved externals
    Build log was saved at "file://c:\Documents and Settings\jcoleman\Desktop\Blackjack\Blackjack\Debug\BuildLog.htm"
    Blackjack - 2 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Any ideas as to why this is happening?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Add
    play_instance Play_State::Play_State;
    To your class source file.
    In case you haven't done so.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Which class source file are you referring to?

    play_instance is what Play_State::Instance() should return....

    I can't initialize play_instance because it only exists privately in Play_State, Instance() should return play_instance...
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Wait, let's try that again.
    Play_State Play_State::play_instance;
    Add to Play_State class source file.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Sorry if I seem inept, but I've never seen these sorts of link errors before:

    Code:
    ------ Build started: Project: Blackjack, Configuration: Debug Win32 ------
    Compiling...
    Play_State.cpp
    Linking...
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::init(void)" (?init@Play_State@@UAEXXZ)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::cleanup(void)" (?cleanup@Play_State@@UAEXXZ)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::update(class State_Manager *)" (?update@Play_State@@UAEXPAVState_Manager@@@Z)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::print(class State_Manager *)" (?print@Play_State@@UAEXPAVState_Manager@@@Z)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::handle_events(class State_Manager *)" (?handle_events@Play_State@@UAEXPAVState_Manager@@@Z)
    C:\Documents and Settings\jcoleman\Desktop\Blackjack\Debug\Blackjack.exe : fatal error LNK1120: 5 unresolved externals
    Build log was saved at "file://c:\Documents and Settings\jcoleman\Desktop\Blackjack\Blackjack\Debug\BuildLog.htm"
    Blackjack - 6 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    That is what happens when I add that line of close to the Play_State source file...

    What are you trying to accomplish with that line of code?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Static members of a class must be defined within the source file or you'll get linking errors.
    You can also try a rebuild. Technically, it should work.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    So are the 5 linker errors I currently have coming from my other gamestate classes not looking like the one we just changed? I've rebuilt the project and it still does not compile, I'm trying in VS2005 express.
    Last edited by Shamino; 01-15-2008 at 02:53 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Dang.
    A good question would be - why do you need a static variable of its own type in the class?
    Now, another one for you: are you actually defining all those functions, init, handle_events is your Play_State source file?
    Is there a
    void Play_State::init()
    there?
    Last edited by Elysia; 01-15-2008 at 02:57 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I think the new errors you're getting are because you don't have those functions defined (only declared). Add function bodies for them in your .cpp file.

  10. #10
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I manage to acquire 5 more linker errors every time I do this to one of my gamestate classes, now I have this:

    Code:
    ------ Build started: Project: Blackjack, Configuration: Debug Win32 ------
    Compiling...
    Menu_State.cpp
    Linking...
    Menu_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Menu_State::init(void)" (?init@Menu_State@@UAEXXZ)
    Menu_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Menu_State::cleanup(void)" (?cleanup@Menu_State@@UAEXXZ)
    Menu_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Menu_State::update(class State_Manager *)" (?update@Menu_State@@UAEXPAVState_Manager@@@Z)
    Menu_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Menu_State::print(class State_Manager *)" (?print@Menu_State@@UAEXPAVState_Manager@@@Z)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::init(void)" (?init@Play_State@@UAEXXZ)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::cleanup(void)" (?cleanup@Play_State@@UAEXXZ)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::update(class State_Manager *)" (?update@Play_State@@UAEXPAVState_Manager@@@Z)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::print(class State_Manager *)" (?print@Play_State@@UAEXPAVState_Manager@@@Z)
    Play_State.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Play_State::handle_events(class State_Manager *)" (?handle_events@Play_State@@UAEXPAVState_Manager@@@Z)
    C:\Documents and Settings\jcoleman\Desktop\Blackjack\Debug\Blackjack.exe : fatal error LNK1120: 9 unresolved externals
    Build log was saved at "file://c:\Documents and Settings\jcoleman\Desktop\Blackjack\Blackjack\Debug\BuildLog.htm"
    Blackjack - 10 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  11. #11
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    It looks like you only have the declarations for those functions... did you actually code the functions that the linker is complaining about? And are you certain they're being compiled/linked?
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  12. #12
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Quote Originally Posted by cpjust View Post
    I think the new errors you're getting are because you don't have those functions defined (only declared). Add function bodies for them in your .cpp file.
    Good eye, let me see if I can clear up some errors this way..
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Actually, make life easier for us and show the source files you have now.

    Quote Originally Posted by cpjust View Post
    I think the new errors you're getting are because you don't have those functions defined (only declared). Add function bodies for them in your .cpp file.
    I have a feeling it's that too

    I believe you're confused about inheritance a little, Shamino?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I guess this is what happens naturally when you dont complete your code bahaha

    That solved the problem cpjust, thanks alot!

    It was just a matter of not realizing the compiler would complain if I didn't add the implementations into the source files..
    I thought it would automatically assume an empty function body :d
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah well, you can see that the linker complains about missing symbols.
    unresolved external symbol "public: virtual void __thiscall Menu_State::init(void)"
    Pretty much reads: "Unable to find the function virtual void Menu_State::init()".
    But yes, cpjust beat me to it by just a hair :/
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linking errors with static var
    By Elysia in forum C++ Programming
    Replies: 8
    Last Post: 10-27-2007, 05:24 PM
  2. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. Static variables and functions problem in a class
    By earth_angel in forum C++ Programming
    Replies: 16
    Last Post: 09-15-2005, 12:08 PM
  5. linker error, using static member
    By Chiel in forum C++ Programming
    Replies: 6
    Last Post: 06-28-2003, 08:40 PM