1

I'm following this singleton pattern, why error LNK2001: unresolved external symbol in this case? my problem LOOKs similar, but my issue is not with the definition of the static instance. My problem is is resolving the static GetInstance() definition from another class.

My errors seems different, or previous answers are inadequate. I've tried the suggestions, "You need to define s_instance outside the class" which doesn't make sense to me as a cpp noob. I declare the statics in the header, and define their implementation in the cpp as well.

I also don't need a lecture on thread safety of singletons, handler bindings use signals2...

State.h

class State
{   
public: 
    State(void);
    ~State(void);

    static State* instance; 
    static State* GetInstance(); 
... 

};

State.cpp

State::AppState mCurrentState;
boost::signals2::signal<void ()> mSignal;


State* instance = NULL;
State* GetInstance()
{
    if( instance == NULL)
    {
        instance = new State();
        return instance;
    }
    else
    {
        return instance;
    }
}

All that compiles fine. Then when I try to access the singleton like this State *state = State::GetInstance();, I get 'unresolved external symbol' error.

error LNK2019: unresolved external symbol "public: static class State * __cdecl State::GetInstance(void)" (?GetInstance@State@@SAPAV1@XZ) referenced in function "public: virtual void __thiscall MesherApp::setup(void)" (?setup@MesherApp@@UAEXXZ)

Also tried the following since some say "define outside of class" - what does that even mean?

class State
{
   public:
   ...
}
static State* instance; 
static State* GetInstance(); 

Looking at this question, Static method with a field I don't see how this applies. I am declaring in the .h and defining everything in the cpp file.

Community
  • 1
  • 1
FlavorScape
  • 13,301
  • 12
  • 75
  • 117

2 Answers2

5

Can you simplify?

class State
{
   public:

      static State& GetInstance() 
      {
          static State _instance; 
          return _instance;
      }
};

See, it's hidden, it's on-demand, it's thread safe and it works without hoop-jumping.

The static initialization ensure the equivalent of instance == NULL there without any additional effort. It also ensures proper destruction at (before) process shutdown (assuming normal termination).

The only assumption this made is that you don't want to be able to 'forcibly' reset the singleton instance.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • By having no threading issues. I'm, of course, speaking of the initialization of the singleton, which is the responsibility here. Whether or not `State` itself is thread-safe, it up to you. (**IOW** My solution is more threadsafe than the code you showed) – sehe Sep 12 '13 at 23:01
  • By the way, see the c++11 standard quote on thread-safe initialization of function-local statics here: http://stackoverflow.com/a/7923623/85371 and http://stackoverflow.com/questions/1270927/are-function-static-variables-thread-safe-in-gcc – sehe Sep 12 '13 at 23:03
  • Ah, I was just informed by a coworker that static (inside the method GetInstance) was the original C version of static (before all the other uses of static were invented). – FlavorScape Sep 12 '13 at 23:03
  • I'm tempted to say he/she might be confusing the many meanings of static. Possibly he/she's just older :/ I'd say read [here about the `static` keyword](http://stackoverflow.com/questions/4615192/why-does-the-static-keyword-have-so-many-meanings-in-c-and-c) and [here about your linker error](http://stackoverflow.com/questions/195207/unresolved-external-symbol-on-static-class-members) – sehe Sep 12 '13 at 23:06
2

I think sehe answer is appropriate and if I would ever find my self using singleton I would take that root.

On the other hand the problem with your code is here:

State* instance = NULL;

It should be

State* State::instance = NULL;

I also just noticed another mistake which is:

State* GetInstance()
{
    //...
}

should be:

State* State::GetInstance()
{
    //...
}
North-Pole
  • 610
  • 4
  • 13