1

Hope some one could help me with this very trivial error which I have not idea how to proceed :)

Here's the header file:

#ifndef __InputHandler__
#define __InputHandler__
#include "SDL.h"
#include <SDL_image.h>
#include <vector>
#include <iostream>

enum mouse_buttons {
    LEFT = 0,
    MIDDLE = 1,
    RIGHT = 2,
};

class InputHandler {
public:
    bool getMouseButtonState(int buttonNumber) {
        return m_mouseButtonStates[buttonNumber];
    }

    std::vector<bool> m_mouseButtonStates;

    static InputHandler* Instance() {
        if (s_pInstance == 0) {
            s_pInstance = new InputHandler();
        }
        return s_pInstance;
    }

    void update();
    void clean();

private:
    InputHandler();
    ~InputHandler() {}
    static InputHandler* s_pInstance;
};
#endif

And I call the InputHandler::Instance() function in another class definition Player.cpp

#include "InputHandler.h"

void Player::handleInput() {
    if (InputHandler::Instance()->getMouseButtonState(LEFT)) {
        m_velocity.setX(1);
    }
}

Here's the error that I get:

Player.obj : error LNK2001: unresolved external symbol 
    "private: static class InputHandler * InputHandler::s_pInstance"

I honestly don't know what's going on and what the error is pointing to. REALLY REALLY appreciate your wisdom :)))

NetVipeC
  • 4,402
  • 1
  • 17
  • 19
Dai Dao
  • 11
  • 2
  • 1
    You must provide a definition of the static member `s_pInstance` outside the class declaration. – user657267 Aug 07 '14 at 03:41
  • Since s_pInstance is a pointer type variable, do I declare it as a global variable in my Player.cpp? Like so? – Dai Dao Aug 07 '14 at 03:47
  • static InputHandler* s_pInstance = 0; – Dai Dao Aug 07 '14 at 03:48
  • Thanks that works like a charm. Would you mind explaining for a bit what you did there that made it work? – Dai Dao Aug 07 '14 at 04:02
  • @DaiDao You mean why the local static variable works? It's guaranteed to be instantiated at the first call to the `InputHandler::Instance()` function, and that the instantiation is thread safe at least. There's more information, but you should ask for particular misunderstandings/misconceptions please. If my answer helped you, you may consider accepting it ;) ... – πάντα ῥεῖ Aug 07 '14 at 04:22

1 Answers1

1

"I honestly don't know what's going on and what the error is pointing to. "

The linker error message pretty much tells you what's missing.
The current problem you have, is you're missing a definition for the static InputHandler* s_pInstance; member in a translation unit. It should look like this:

InputHandler* InputHandler::s_pInstance = 0;

Though your approach to the singleton pattern has some flaws and deficiencies (especially regarding thread safety). You should simplify your singleton pattern like this:

 static InputHandler& Instance() {
    static InputHandler theInputHandler;
    return theInputHandler; 
 }

or if you insist using a a pointer

 static InputHandler* Instance() {
    static InputHandler theInputHandler;
    return &theInputHandler; 
 }

This is commonly known as 'Scott Meyer's Singleton idiom', here's some more information about the original reasonings;

C++ and the Perils of Double-Checked Locking

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190