2012-06-13 40 views
3

如果我在基類非QObject類中聲明一個函數爲虛函數,然後將其重疊爲具有Q_OBJECT宏且QObject爲一的派生類中的一個插槽基類是否應該工作正常?可以使用基類非QObject類的slotify虛函數

確保虛擬通話可以正常工作嗎?如果連接派生類的插槽,會發生什麼?

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

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

顯然,你的問題似乎有一些不同的解釋。你能澄清一下,例如添加一些示例代碼嗎? –

+0

這個問題並不真正相關,但你應該知道['QObject'必須首先出現在基類列表中](http://qt-project.org/doc/qt-4.8/moc.html#multiple-繼承的需要,QObject的將要優先)。 –

+0

@LucTouraille確實不相關。固定。 – Vasaka

回答

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函數。

+2

這並沒有真正解決這個問題。 –

+0

@LucTouraille你爲什麼這麼想?我認爲它清楚地表明插槽表現爲_normal_函數('虛擬'或不)。最後,槽調用導致函數調用,所以應該正確處理虛擬性。 –

+0

@JohannesS .:根據我的理解,問題並不在於框架明確允許的虛擬插槽(如Riateche所述),而是關於將現有成員函數從基類轉換爲派生類中的插槽類(有額外的潛在問題,即基類甚至不是QObject)。 –

相關問題