3

基本の非QObjectクラスで仮想関数を宣言し、それをQ_OBJECTマクロを持ち、基本クラスの1つとしてQObjectを持っている派生クラスのスロットとして上書きすると、問題なく動作するはずですか?

仮想通話が機能することは保証されていますか?派生クラスのスロットに接続するとどうなりますか?

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

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

1 に答える 1

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ます。また、はQObjectベースではないため、そのインスタンスを関数Baseに渡すことはできません。connect

于 2012-06-13T21:50:38.897 に答える