是否可以插入基本非QObject类的虚函数

时间:2012-06-13 21:46:17

标签: c++ qt

如果我在基本的非QObject类中声明一个虚函数,然后将它作为一个插槽重叠在具有Q_OBJECT宏的派生类中,并且将QObject作为其中一个基类,它应该可以正常工作吗?

是否可以保证虚拟通话有效?如果你连接到派生类的插槽会发生什么?

class Base
{
public:
    virtual void f();
};

class Derived: public QObject, public Base
{
    Q_OBJECT
public slots:
    virtual void f();
};

1 个答案:

答案 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函数。