`Qt`沒有透過`QCoreApplication::exec()`或`QEventLoop::exec()`驅動事件分發器時,處理延遲刪除的具體例子

MarsCactus發表於2024-11-18

以下是一個使用C++和Qt框架來演示在Qt沒有透過QCoreApplication::exec()QEventLoop::exec()驅動事件分發器時,處理延遲刪除的具體例子,假設我們有一個簡單的自定義類,它在析構時需要執行一些清理工作,並且希望利用延遲刪除機制:

1. 自定義類定義

首先建立一個簡單的自定義類MyObject,它繼承自QObject,並且在解構函式中有一些列印語句用於模擬清理操作:

#include <QObject>
#include <iostream>

class MyObject : public QObject
{
    Q_OBJECT
public:
    MyObject() {}
    ~MyObject() {
        std::cout << "MyObject is being deleted and performing cleanup." << std::endl;
    }
};

2. 不使用常規事件迴圈的情況及變通方法示例

通常情況下,如果在基於QCoreApplication::exec()的常規應用中,當物件被設定為延遲刪除(例如使用deleteLater()函式)時,Qt會在事件迴圈的適當時候自動處理這個刪除操作並呼叫解構函式。但現在假設我們沒有啟動常規的事件迴圈,程式碼如下:

#include <QCoreApplication>
#include <QTimer>

int main(int argc, char *argv[])
{
    // 這裡不啟動常規的QCoreApplication事件迴圈
    // QCoreApplication a(argc, argv); 

    MyObject* obj = new MyObject();
    // 正常我們可能會呼叫obj->deleteLater();期望自動延遲刪除
    // 但現在沒有事件迴圈驅動,不會自動處理

    // 變通方法,使用單次觸發的定時器來模擬事件迴圈對延遲刪除的處理
    QTimer::singleShot(0, obj, &MyObject::deleteLater);
    // 這裡我們手動模擬事件迴圈的單次迭代來處理定時器等事件,觸發延遲刪除
    QCoreApplication::processEvents();

    return 0;
}

在上述程式碼中:

  • 首先我們註釋掉了QCoreApplication a(argc, argv);這行程式碼,意味著沒有啟動常規的Qt應用事件迴圈,也就是處於Qt不透過QCoreApplication::exec()驅動事件分發器的情況。
  • 我們建立了一個MyObject型別的指標obj,如果是在正常有事件迴圈的應用中,呼叫obj->deleteLater();後,Qt會自動在合適的事件迴圈週期內處理這個物件的刪除(呼叫解構函式)。但現在沒有事件迴圈,不會自動處理。
  • 為了變通處理,我們使用了QTimer::singleShot(0, obj, &MyObject::deleteLater);,這表示建立一個單次觸發的定時器,定時器一啟動(這裡時間間隔設為0,表示立即觸發)就會呼叫objdeleteLater()函式,將其標記為延遲刪除。
  • 最後透過QCoreApplication::processEvents();手動去處理一下事件,這樣就能模擬事件迴圈去處理這個延遲刪除的操作,使得MyObject的解構函式得以被呼叫,進而執行裡面模擬的清理工作(這裡就是列印語句所表示的內容)。

請注意,這只是一個簡單的示例用於說明在特定情況(無常規事件迴圈)下如何處理延遲刪除的變通方法,實際應用場景可能會更復雜,需要根據具體的程式邏輯和需求來合理調整程式碼。

另外,如果涉及到更復雜的物件關係、多執行緒等情況,還需要考慮更多諸如物件的父子關係管理、執行緒安全等方面的問題,確保延遲刪除操作按照預期執行且不會引發程式錯誤。

相關文章