2010-06-28 134 views
17

Wikipedia表示「如果代碼中的運行時失敗不會產生不良影響,如內存泄漏,亂碼存儲數據或無效輸出,則說一段代碼是異常安全的。即使發生異常,異常安全代碼也必須滿足代碼上的不變量。「Qt中的異常安全

而且看起來我們需要異常處理以確保異常安全。另一方面,只要我看到,異常處理在Qt應用程序中並不是非常流行。

Qt中的哪些最佳實踐可以滿足異常安全性?你用什麼來代替異常處理?

+1

QT是一個非常古老的圖書館,在異常安全方面非常差。考慮如何將所有小部件分配到堆中,但是RAII沒有智能指針。最好的辦法是將它們分配到auto_ptr中,並在插入時將內存釋放到父級/佈局。他們有一些基本的規定,比如QMutexLocker,因爲拋出一個互斥鎖被鎖定會是災難性的,但是他們需要提供更多的工作或者一大堆工作,您必須自己去做,以便以一種異常安全的方式使用qt 。 – stinky472 2010-06-28 13:59:32

+8

@ stinky472:錯了。 [QSharedPointer](http://doc.trolltech.com/4.6/qsharedpointer.html) – MSalters 2010-06-28 14:25:44

+0

@ stinky472:哪個GUI工具包允許小部件被堆棧分配?你爲什麼要這樣做?聽起來像是一個「稻草人」的說法。 – kevinarpe 2011-12-30 08:50:46

回答

10

C++有錯誤時拋出安全一個非常強大的機制。由於例外,析構函數針對所有超出範圍的變量運行。這與Java等語言不同,其中異常安全性要求程序員正確地獲得catchfinally條款。

調用析構函數的C++行爲可以與堆棧中的Qt對象無縫協作。 Qt類都具有析構函數,並且都不需要手動清理。此外,QSharedPointer<T>可用於管理堆分配的Qt對象;當最後一個指針超出範圍時,該對象被銷燬。這包括指針由於例外而超出範圍的情況。

因此,Qt中肯定存在異常安全。這只是透明的。

+2

我認爲QSharedPointer的問題在於它沒有在很多地方使用。例如,QLayout期望QWidget *具有QLayout成爲其內存管理器的期望。我們不能在這裏使用QSharedPointer,因爲QLayout在從佈局中移除時應該刪除它。 :-( – stinky472 2012-01-31 19:50:33

+3

)作者的原帖稱:「只要我看到Qt應用程序中的異常處理並不是非常流行」,QSharedPointer的存在並不會改變,因爲QT API及其示例的很少部分實際上使用它。而是我們有一些例子,如QButton * button = new QButton(...); QVBoxLayout * layout = new QVBoxLayout(...);這個庫在大多數情況下不會被編碼爲異常安全。應該加以解決,並讓圖書館的更多部分接受和存儲QSharedPointer將是一個非常好的解決方案。 – stinky472 2012-02-01 15:26:46

2

我最好的做法是不要在基於Qt的代碼中使用(或至少避免它們)C++異常,這使得處理它們不成問題。但Qt並不是真正的原因,我只是覺得異常往往會使事情變得不必要地複雜得多。但它可以幫助的Qt本身大多是例外的煩惱免費... :)

7

Qt是(主要)也不例外安全:http://doc.qt.io/archives/4.6/exceptionsafety.html

在另一方面處理異常正確的事件驅動編程很難 ,所以最好的 是爲了避免他們在使用Qt和傳遞錯誤代碼。

+10

爲什麼在事件驅動編程中正確處理異常是非常困難的? – metdos 2011-04-07 13:37:25

1

Qt等級爲exception neutral,如documentation中所述。

你應該堅持使用布爾值來處理錯誤條件,就像Qt本身一樣。

由於Qt必須支持許多不同的平臺(可移植性和異常不能很好地混合在一起),所以不會在內部使用異常。

再次,從文檔:

目前,唯一支持的用例用於從內Qt的拋出的異常中恢復(例如,由於內存不足)是退出事件循環和之前做一些清理退出應用程序。 典型使用案例:

QApplication app(argc, argv); 
... 
try { 
    app.exec(); 
} catch (const std::bad_alloc &) { 
    // clean up here, e.g. save the session 
    // and close all config files. 

    return 0; // exit the application 
} 
+4

請注意,Qt的歷史可以追溯到異常是新的時候。在21世紀的便攜性要容易得多。 – MSalters 2010-06-28 08:30:14

+0

你說得對,我應該強調這一點。儘管我對真正的異常和Symbian知之甚少,尤其是對於更新的版本。我知道舊版本使用了一種截然不同的異常處理機制。 – 2010-06-28 08:48:21

+0

Symbian是一種痛苦;鑑於其20世紀80年代EPOC的根源,這並不意外但是Qt和Symbian沒有關係。 Symbian發源於Psion; Qt在TrollTech。 – MSalters 2010-06-28 14:34:04