2012-03-22 17 views
2

不太確定如何制定我的問題,我希望這更清楚。我想有一個基類,看起來是這樣的:是否可以使用「this」從派生對象的基類發出信號

class Base : public QObject { 
    Q_OBJECT 


    void doSomething() { emit test(this); } 

    virtual void doSomethingElse() = 0; 

signals: 
    void test(Base*); 
} 

然後在派生類中做到這一點:

class Derived : public Base { 

    void doSomethingElse() { emit test(this); } 

} 

如果我現在聽這個對象的信號,做我聽測試(Derived *)或/和測試(Base *)?

+0

你能否具體說明「聽」的意思 - 在這種情況下,很多事情都依賴於它,例如聽 - 將發送者作爲參數傳遞給slot或...? – milyaaf 2012-03-22 07:25:41

+0

通過「連接(objectInMyExample,SIGNAL(試驗(基站* /派生*)),someOtherObject,SLOT(handleObject(基* /派生*))) – chikuba 2012-03-22 22:36:47

+0

確定,所以在handleObject(基*)將把手基座和連接它handlObject(導出*),它會聽派生。 – milyaaf 2012-03-23 08:40:06

回答

1

商務部在編譯時將基於您宣稱他們在使用類的方式插槽和信號的清單宏觀Q_OBJECT
這個列表是一個字符串列表,所以如果你聲明:

signals: 
    void test(Base*); 

在列表中的項目將是字符串"test(Base*)"(您可以在輸出目錄中看到這個文件moc_yourclass.cpp的變量qt_meta_YourClass該列表)。
SIGNALSLOT也返回字符串,connect()推崇他們,使他們的格式爲從商務部生成列表中的一個,並將它們與那些在該列表中。

當你派生類,串並沒有改變,所以你仍然必須使用SIGNAL(test(Base*))

+0

我應該讓信號虛擬嗎?或者更好從基類 - >派生類而不是使用發件人並從QOBject轉換到基類/派生類? – chikuba 2012-03-22 20:52:02

+0

技術上是,即使moc會給你一個警告。而且C++不支持協變或逆變參數,所以'test(Base *)'和'test(Derived *)'是無關的。您仍然可以通過虛擬函數或使用訪問者模式來避免通過執行依賴於對象爲「Base *」或「Derived *」的對象本身進行投射。 – alexisdm 2012-03-22 22:28:53

+0

hm。所以如果我明白你正確的話,如果我的基類中的函數是虛擬的,那麼無論我是否得到一個指向Base *的指針,我都會得到虛函數等等。 – chikuba 2012-03-22 22:34:28

1

您不應該包含發件人作爲信號的參數。您只需使用QObject::sender()即可獲得發送信號的QObject

如:

emit test(); 

然後在一個槽:

void Listener::someObject_test() { 
    QObject* sender = QObject::sender(); 
    // or: 
    Derived* sender = (Derived*)QObject::sender(); 
} 
+1

我認爲文檔是安劍錚,卓傑寄件人()? – chikuba 2012-03-22 02:39:49

+0

我用了幾次,從來沒有任何問題的。該文件指出「此功能違反了模塊化的面向對象的原則「如果你提供對象作爲信號的參數,它也會違反相同的原則,有時需要知道信號來自哪裏,在這種情況下,使用'QObject :: sender()'是最簡單的 – 2012-03-22 03:46:49

+1

'sender()'不是空閒的,它鎖定一個互斥鎖並執行一個列表查找。如果你傳遞了這個對象作爲信號的參數,它在語義上表示該對象是消息的一部分,不必使用演員使用你的對象,它也適用於信號和插槽屬於不同的線程不同於'sender()'。作爲獎勵,你甚至可以用一個對象作爲不是發送者的參數發出信號。 – alexisdm 2012-03-22 14:06:13

0

由於派生類沒有自己的信號,所以您將聽取測試(Base *)。

相關問題