keypressevent及其重载

时间:2016-04-30 21:28:18

标签: c++ qt oop

我有一个以下类来处理转义键按下。

         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的受保护方法。   所以初始代码只是重载了那个方法,不是吗?并且过载起作用。但是为什么一个全新版本的方法具有另一个名称但相同的实现不起作用?

1 个答案:

答案 0 :(得分:2)

不是overload,它是override函数的virtual。 阅读c++ virtual个函数。

例如:

#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,因为for ptr->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指向Boo类虚拟表,address_of_function将等于&Boo::f,这就是virtual函数的工作原理。

所以在你的情况下Foo == QWidget并且它在Qt内有这样的代码:

this->keyPressEvent();

,它在虚拟表中获取keyPressEvent的地址,然后调用它。显然,如果你实现KeyPress::someOtherFunction,它将不被调用,因为已编译的Qt代码没有调用它。