我有一个完整的静态类,使用std :: map
简化案例
·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;
}
但是静态成员变量存在问题,因为我得到了
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
当我删除它时,它运行正常
为什么我会遇到这个问题,使用静态变量时应该没有问题:/
感谢
答案 0 :(得分:7)
您需要在.cpp文件中定义pressed
地图:
#include "Keyboard.h"
std::map<char, bool> Keyboard::pressed;
// The rest as before
答案 1 :(得分:6)
您应该将其添加到.cpp文件
std::map<char, bool> Keyboad::pressed;
将静态类成员视为全局变量。编译器应该在唯一的目标文件中为它们分配内存。所以你应该在相应的源文件中定义它们。
答案 2 :(得分:2)
类定义中的静态成员只是一个声明。您 仍然必须提供定义,就像你为 功能。只需添加
std::map<char, bool> Keyboard::pressed;
在某个源文件中。 (对于映射char
,您也可以
考虑一个简单的
bool Keyboard::pressed[256];
,使用转换为char
的{{1}}编制索引。)
答案 3 :(得分:1)
考虑一个更简单的案例。全局变量counter
在多个标头文件中声明:
int counter; // This appears in 3 HEADER files.
很少有源文件可以引用它。当您编译并链接它时,编译器会发出链接器错误,指出已在某些.OBJ文件集中定义counter
(错误消息依赖于编译器)。
要解决此问题,您只需将extern
放在变量前面(在所有标题文件中):
extern int counter; // This appears in 3 HEADER files.
当你重建它时,链接器会抱怨counter
没有在任何地方定义。
要解决此问题,您在一个源文件(任何一个)中定义此变量:
int counter;
它解决了这个问题。
类的静态变量只是一个全局变量,可以通过classname::variablename
格式访问。可访问性是相同的 - 全局。