2010-06-28 87 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