簡體   English   中英

在Qt中從對象的析構函數發出信號是否可以?

[英]Is it OK to emit a signal from an object's destructor in Qt?

當一個QObject派生的對象被破壞時,從它的析構函數發出信號是否可以? 我嘗試了它似乎工作,但我不確定是否應該這樣做。

例如,這段代碼

class MyClass : public QObject {
signals:
    void mySignal(const QString &str);
public:
    QString myString;
    ~MyClass() { emit mySignal(myString); }
}

會在執行連接的插槽時將const引用傳遞給可能超出范圍的對象。

排放通常很好(QObject也會使用“已破壞”的信號),包括你的情況。 當連接是直接連接時,字符串仍然存在。 當它是QueuedConnection時,則首先將字符串復制到事件循環中。

如果你問它是否可以:是的,它本身不會引起任何問題。

如果您在Qt中詢問它是否通常是安全的事情? 絕對不安全。 如果從析構函數發出,並且對Qt事件系統有很好的理解,你必須非常注意你所做的事情。

請記住,當一個QObject后代破壞時,它會斷開所有信號,因此被破壞的對象不會再對其插槽進行調用了嗎? 好吧有一個問題:破壞秩序。 QObject析構函數斷開連接,並且它是最終的破壞,意味着,在銷毀鏈中,事件可能仍然到達“半死”對象,從而在訪問虛擬函數和已經被破壞的后代的成員時導致訪問沖突。 如果您使用事件系統,則可能存在以下任何條件:

  • 在多線程環境中,如果對象沒有在自己的線程上被破壞。
  • 在多線程環境中,如果對象的銷毀鏈在任何運行路徑上觸發processEvents()運行。
  • 在多線程環境中,如果另一個線程上的任何對象與此對象有直接連接,則它無法直接連接對其被破壞的信號作出反應。
  • 在單線程環境中,當析構函數發送可能返回到直接連接鏈中的對象的信號時。

我將此效應稱為“死亡期間的生命”,並在析構函數中發出信號或運行任何形式的processEvents() (通常是意外)會增加創建此類錯誤的機會。

當然,如果你能以某種方式保證在破壞期間不會有任何現在或未來的代碼實際觸發任何插槽,它從析構函數中發出它是非常安全的,但很難給出這樣的保證,我建議只要有可能就避免使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM