2013-05-22 3 views
0

Я написал механизм обработчика событий, который работает очень хорошо. Так что я продлил его более обобщенным и написал обработчик события, чтобы дать мне состояние клавиатуры:Должны ли статические объекты иметь статические переменные-члены?

class KeybdHandler : public EventHandler<KeybdHandler> 
{ 
private: 
    Keyboard _keybd; 

public: 
    void SetEvent(const Keyboard::KeyEvent & evt) 
    { 
     Keyboard::KeyEvent e = evt; 

     // event holds the new keystate 
     Notify(&e); 

     // keystate is saved to keyboard 
     _keybd.SetKey(e._Key, e._bKeyDown); 
    } 

    Keyboard & GetKeybd() { return _keybd; } 
}; 

static KeybdHandler g_evtKeybd; 

Переменная KeybdHandler :: Клавиатура держит массив, который обозначает состояние клавиатуры (например, одна запись на ключ и BOOL переменная, обозначающая keydown или keyup).

Поэтому я создаю статический экземпляр этого класса KeybdHandler.

Но когда я вызываю g_evtKeybd.GetKeybd(), состояние клавиатуры всегда пусто/пусто/все в состоянии keyup.

Когда я делаю переменную KeybdHandler :: Keyboard static, GetKeybd() возвращает объект Keyboard с сохраненным состоянием.

Почему переменная Keyboard статична, если объект, содержащий объект, является статическим?

EDIT: Сразу хочу уточнить, что SetEvent всегда вызывается через статическую переменную:

g_evtKeybd.SetEvent(Keyboard::KeyEvent((int)key, true)); 

EDIT2: Я не уверен, если это актуально. Класс KeybdHandler находится в статической библиотеке и связан с другим исполняемым файлом.

+0

Наследование от шаблонов - это не то, что я часто делаю, поэтому извините меня, если это не имеет значения или неверно, но из определения класса KeybdHandler наследует шаблон типа KeybdHandler (тот же класс). Разве это не означает, что у вас есть несколько версий тех же переменных класса, поэтому тот, который вы устанавливаете, не тот, который вы извлекаете? Если это так, распечатайте адрес нестатических переменных в get и set accessors и посмотрите, совпадают ли они. – TheDarkKnight

+0

@ Merlin069, родительский класс не очень уместен, см. Http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – fishfood

+1

Это действительно интересно. Спасибо за ссылку. – TheDarkKnight

ответ

1

В качестве глобальной статической переменной вы объявили g_evtKeybd. В этом контексте static имеет другое значение. Каждый блок компиляции будет иметь свой собственный экземпляр g_evtKeybd, который, вероятно, не тот, который вы намеревались. Поскольку статические члены разделяются всеми экземплярами класса, все они возвратятся одинаково, даже если у вас есть несколько экземпляров (скрывающих вашу фактическую ошибку).

+0

Думаю, вы нанесли ему гвоздь на голову. Спасибо Джо. Я думаю, что мне придется сделать синглтонов из обработчиков keybd и mouse :) – fishfood

Смежные вопросы