0

i have a full static class, using a std::map

thats the simplified case

.h

#ifndef KEYBOARD_H
#define KEYBOARD_H

#include <map>

class Keyboad {

    static std::map<char, bool> pressed;    

    static void keyPressedEvent(char _key); 

};

#endif

.cpp

#include "Keyboard.h"

void Keyboard :: keyPressedEvent(char _key) {

    Keyboard :: pressed[_key] = true;

}

but there is a problem with the static member variable, because i get

Undefined symbols:
"Keyboard::pressed", referenced from:
__ZN15Keyboard7pressedE$non_lazy_ptr in Keyboard.o
(maybe you meant: __ZN15Keyboard7pressedE$non_lazy_ptr)
ld: symbol(s) not found
collect2: ld returned 1 exit status

when i remove it, it runs ok

why do i get this problem, there should be no problem when using a static variable :/

thanks

4 Answers 4

7

You need to define the pressed map in your .cpp file:

#include "Keyboard.h"
std::map<char, bool> Keyboard::pressed;

// The rest as before
Sign up to request clarification or add additional context in comments.

4 Comments

but why, when its already declared in class Keyboad which i include?
@Peter, it is declared in your class, but not defined.
@Peter: Think of the header file as a description of what your class "includes" (this is called declaration). It is enough to let you compile the code, but to link it into an executable you also need to "produce the actual goods". That's what the extra line above does (this is called definition).
ok, but when i want to use the class somewhere else, i dont need to declare it (i just call Keyboard::foo), because its static functions and (members? and now iam confused) get defined automaticly
6

You should add this to .cpp file

std::map<char, bool> Keyboad::pressed;

Consider static class members as global variables. Compiler should allocate memory for them inside of the only object file. So you should define them in corresponding source file.

Comments

2

A static member in the class definition is just a declaration. You still have to provide the definition, exactly like you did for the function. Just add

std::map<char, bool> Keyboard::pressed;

in a source file somewhere. (For mapping chars, you might also consider a simple

bool Keyboard::pressed[256];

, indexed with the char converted to unsigned char.)

Comments

1

Consider a simpler case. A global variable counter is declared in multiple header files:

int counter; // This appears in 3 HEADER files.

Few source files do refer it. When you compile and link it, compiler would emit linker error saying that counter is already defined in some set of .OBJ files (Error message is dependent on compiler).

To solve this, you just put extern in front of variable (in all header files):

extern int counter; // This appears in 3 HEADER files.

And when you rebuild it, linker will complain that counter is not defined anywhere.

To solve this issue, you define this variable in one source file (any one):

int counter;

And it resolves the issue.

The static-variable of class is nothing but a global variable, which can be accessed by classname::variablename format. The accessibility is same - global.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.