如果我声明在基非QObject的类的虚拟函数,然后overlaod它作为在具有Q_OBJECT宏和具有QObject的作为基类的一个派生类中的时隙它应该工作好吗?
是否可以保证虚拟呼叫能够正常工作?如果你连接到派生类的插槽会发生什么?
class Base
{
public:
virtual void f();
};
class Derived: public QObject, public Base
{
Q_OBJECT
public slots:
virtual void f();
};
Run Code Online (Sandbox Code Playgroud)
是:
由于插槽是普通的成员函数,因此它们在直接调用时遵循正常的C++规则.<...>您还可以将插槽定义为虚拟插槽,我们发现这些插槽在实践中非常有用.
http://qt-project.org/doc/qt-4.8/signalsandslots.html#slots
在您的示例中Derived::f是一个普通的虚函数.如果直接调用它,它就像预期的那样工作,就像文档说的那样.当由signal调用时,它被调用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);
}
Run Code Online (Sandbox Code Playgroud)
因此,它以正常的函数调用结束_t->f().
请注意,无法Base::f通过信号调用.仅当当前对象实际是Base实例而不是Derived实例时,才能执行此功能.而且由于Base不是基于QObject的,因此无法将其实例传递给connect函数.