2013-05-22 67 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 ::键盘变量保存表示键盘状态的阵列每个键和布尔(如一个条目表示keydown或keyup的变量)。

所以我创建了这个KeybdHandler类的静态实例。

但是当我调用g_evtKeybd.GetKeybd()时,键盘状态总是为空/空白/全部。

当我使KeybdHandler :: Keyboard变量为静态时,GetKeybd()返回一个保存状态的Keyboard对象。

如果包含的对象是静态的,为什么Keyboard变量必须是静态的?

编辑: 只是想澄清,SetEvent的总是通过静态变量称为:

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

EDIT2: 我不能肯定,如果是相关的。 KeybdHandler类位于静态库中,并链接到另一个可执行文件。

+0

从模板继承不是我经常做的事情,所以请原谅,如果这是无关紧要或错误的,但从类的定义中,KeybdHandler会继承类型为KeybdHandler(相同类)的模板。这并不意味着你有相同的类变量的多个版本,所以你设置的不是你正在检索的那个?如果是这样,请在get和set访问器中输出非静态变量的地址,并查看它们是否匹配。 – TheDarkKnight

+0

@ Merlin069,父类并不真正相关,请参阅http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – fishfood

+1

这真的很有趣。感谢您的链接。 – TheDarkKnight

回答

1

您将g_evtKeybd声明为全局静态变量。在这种情况下,static具有不同的含义。每个编译单元将拥有自己的g_evtKeybd实例,这可能不是您想要的。由于静态成员由类的所有实例共享,即使您有多个实例(隐藏实际的错误),它们也会返回相同的结果。

+0

我觉得你碰到了那里的头。谢谢乔。我想我必须让单身人士脱离keybd和鼠标处理程序:) – fishfood