2014-11-03 36 views
2

我有以下代碼:瞭解QTimer用Lambda和遞歸函數調用

void class::Testfunc() 
{ 
    QTimer* timer = new QTimer; 
    QObject::connect(timer, &QTimer::timeout, [this](){ 
     emit Log("Time out..."); 
     TestFunc(serverAddress, requestsFolderPath); 
     // deleteLater(); //*** why does this crash if used to replace the connect below? 
    }); 
    connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater); 
    timer->setSingleShot(true); 
    timer->start(1000); 
} 

單觸發定時器與連接到該記錄的入口lambda函數每個第二(打印lambda函數一個timout創建文本到標準輸出)並再次調用該函數。

這工作沒有問題。但是,如果我將deleteLater(在lambda函數下)的連接調用刪除,但在lambda函數中啓用deleteLater調用,則該函數將失敗。它打印一次後不久,在試圖刪除定時器對象時崩潰。

這個實例中的兩個deleteLater調用有什麼區別,以及爲什麼將deleteLater放在lambda函數中會導致問題,而創建單獨的連接則按預期工作,即使兩者都調用deleteLater以響應定時器超時信號?

+2

deleteLater()似乎是你的類,而不是拉姆達內部的定時器,或者是隻是一個錯字? – lpapp 2014-11-03 12:11:34

+0

是的,因爲@lpapp說lambda中的'deleteLater'調用'myclass :: deleteLater'而不是'QTimer :: deleteLater'。因此,確保你同時捕獲'[this,timer]'並使用'timer-> deleteLater();' – PeterT 2014-11-03 12:21:14

回答

5

鑑於沒有打字錯誤或某些我不知道的信息,我認爲原因是因爲您試圖刪除您的class實例,而不是在上述方法中在堆上分配的QTimer實例。

如果您查看非lambda版本,則調用QTimer instance上的deleteLater,因爲這是connect調用中的接收方。

connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater); 

然而,在lambda變型,計時器實例未捕獲和自然,就其目前的版本沒有訪問它,分別。爲了使相當於兩個選擇,這種修改需要做的代碼:

QObject::connect(timer, &QTimer::timeout, [this, timer](){ 
//            ^^^^^ 
    emit Log("Time out..."); 
    TestFunc(serverAddress, requestsFolderPath); 
    timer->deleteLater(); 
// ^^^^^^^ 
}); 
+0

Spot,它是捕獲變量,這是我的問題和簡單的疏忽。謝謝。 – TheDarkKnight 2014-11-03 13:14:32