2016-04-30 60 views
0

我有一个处理退出键按下的类。keypressevent及其过载

  class KeyPress : public QWidget 
     { 
      Q_OBJECT 
      public: 
      KeyPress(QWidget * parent=0); 

      protected: 
      void keyPressEvent(QKeyEvent * event); 

     }; 

和.cpp文件:

  void KeyPress::keyPressEvent(QKeyEvent *event) 
      { 

       if (event->key() == Qt::Key_Escape) { 
        qApp->quit(); 
          } 
      } 

它工作正常,但如果我改变了方法的名称,说,keyPressed(QKeyEvent * event),这是行不通的。根据文档的keyPressEvent(QKeyEvent * event)方法是QWidget的受保护方法。 因此,最初的代码只是重载该方法,不是吗?并且超负荷工作。但为什么具有其他名称但实现相同的方法的全新版本不起作用?

回答

2

它不是overload,它是的virtual函数。 阅读关于c++virtual的功能。

例如:由于对ptr->f()编译

#include <iostream> 

using std::cout; 
struct Foo { /*virtual*/void f() { cout << "foo:f\n"; } }; 
struct Boo : public Foo { void f() { cout << "boo:f\n"; } }; 

int main() 
{ 
    Boo boo; 
    Foo *ptr = &boo; 
    ptr->f(); 
} 

这样的代码打印foo:f,产生这样的事情:

address_of_function = &Foo::f; 
call address_of_function 

,但如果你在我的示例代码的注释去掉virtual将打印boo:f, 由于virtual导致编译器生成类似于这样的代码:

address_of_function = ptr->virtual_table_of_Foo_class[offset_of_f] 
call address_of_function 

ptr点嘘类的虚表,address_of_function将等于&Boo::f,这怎么virtual功能的工作原理。

所以你的情况Foo == QWidget,它有这样的代码的Qt内:

this->keyPressEvent(); 

,这需要在虚拟表keyPressEvent地址,并调用它。很明显,如果你实现了KeyPress::someOtherFunction,它将不会被调用,因为已编译的代码Qt没有调用它。

+0

对不起,这就是我的意思。 Ment覆盖,父函数的不同实现,相同的签名。但问题依然存在。为什么新方法不起作用? – parsecer

+1

@parsecer我已经更新了我的答案。 – fghj

+0

感谢您的回复!但它仍然不完全清楚。是不是我的情况就像'Boo'中有一个'f2()'函数一样,它和'f()'是'cout <<“foo:f \ n'完全相同。 'Boo'对象调用该函数并没有什么错...... – parsecer