我有一个上课的班级,它处理转义键。
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)
,它将无法正常工作。根据docs的keyPressEvent(QKeyEvent * event)
方法是QWidget
的受保护方法。因此,初始代码只是重载了该方法,不是吗?和过载工作。但是,为什么使用另一个名称但具有相同实现的方法的全新版本将不起作用?
最佳答案
它不是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
,因为对于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
的已编译代码无法对其进行调用。