如果我在基本的非QObject类中声明一个虚函数,然后将它作为一个插槽重叠在具有Q_OBJECT宏的派生类中,并且将QObject作为其中一个基类,它应该可以正常工作吗?
是否可以保证虚拟通话有效?如果你连接到派生类的插槽会发生什么?
class Base
{
public:
virtual void f();
};
class Derived: public QObject, public Base
{
Q_OBJECT
public slots:
virtual void f();
};
答案 0 :(得分:8)
是:
由于插槽是普通的成员函数,因此它们遵循普通的C ++ 直接调用时的规则。 < ...>您还可以将插槽定义为虚拟插槽,我们已经找到了 在实践中很有用。
http://qt-project.org/doc/qt-4.8/signalsandslots.html#slots
在您的示例中,Derived::f
是一个普通的虚函数。如果直接调用它,它就像预期的那样工作,就像文档说的那样。当被信号调用时,它由qt_static_metacall
调用,在moc_Derived.cpp
中生成如下:
void Derived::qt_static_metacall(QObject *_o, QMetaObject::Call _c,
int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
Derived *_t = static_cast<Derived *>(_o);
switch (_id) {
case 0: _t->f(); break;
default: ;
}
}
Q_UNUSED(_a);
}
因此,它以正常函数调用_t->f()
结束。
请注意,无法通过信号调用Base::f
。仅当当前对象实际为Base
实例且不是Derived
实例时,才能执行此功能。由于Base
不是基于QObject的,因此您无法将其实例传递给connect
函数。