我有一个以下类来处理转义键按下。
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
的受保护方法。
所以初始代码只是重载了那个方法,不是吗?并且过载起作用。但是为什么一个全新版本的方法具有另一个名称但相同的实现不起作用?
答案 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
代码没有调用它。