当前位置: 首页 > news >正文

Qt异常处理

初步警告:异常安全功能不完整!一般情况下应该可以工作,但类仍然可能泄漏甚至崩溃。

Qt本身不会抛出异常。而是使用错误码, 但是C++可能会抛出异常。此外,有些类有用户可见的错误消息,例如QIODevice::errorString()或QSqlQuery::lastError()。这有历史和现实的原因——打开异常可能会使库的大小增加20%以上。

下面几节将描述Qt在编译时启用异常支持时的行为。

容器

Qt的容器类通常是异常中立的。它们将在包含的类型T中发生的任何异常传递给用户,同时保持内部状态有效。

例子:

QList<QString> list;
...
try {list.append("hello");
} catch (...) {
}
// list is safe to use - the exception did not affect it.

抛出异常的容器类型可能是在在赋值或复制构造期间。对于这些类型,修改容器并返回值的函数使用起来是不安全的:

MyType s = list.takeAt(2);

在赋值s期间发生异常,因为赋值给s之前,索引2处的值已经从容器中移除。它已经被丢弃,没有恢复的机会。
正确的写法是:

MyType s = list.at(2);
list.removeAt(2);

如果赋值操作抛出,容器仍将包含该值;无数据丢失。
注意,隐式共享Qt类不会抛出它们的赋值操作符或复制构造函数,因此上面的限制不适用。

内存不足处理

大多数桌面操作系统都过度使用内存。这意味着即使在分配内存时没有足够的可用内存,malloc()或new运算符也会返回一个有效的指针。在这种系统上,不会抛出std::bad_alloc类型的异常。

在其他所有操作系统上,如果任何内存分配失败,Qt都会抛出类型为std::bad_alloc的异常。如果系统内存不足,或者没有足够的连续内存来分配请求的大小,那么分配可能会失败。

该异常情况有文档说明。例如,如果内存不足,QImage构造函数将创建一个null图像,而不是抛出异常。

从异常中恢复

目前,从Qt中抛出的异常(例如内存不足)中恢复的唯一支持用例是退出事件循环并在退出应用程序之前进行一些清理。

典型用例:

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

抛出异常后,与窗口服务器的连接可能已经关闭。在捕获异常后调用GUI相关函数是不安全的。

客户端代码中的异常

信号与槽位

从Qt的信号槽连接机制调用的槽中抛出异常被认为是未定义的行为,除非它在槽内处理:

State state;
StateListener stateListener;// OK; the exception is handled before it leaves the slot.
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwHandledException()));
// Undefined behaviour; upon invocation of the slot, the exception will be propagated to the
// point of emission, unwinding the stack of the Qt code (which is not guaranteed to be exception safe).
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwUnhandledException()));

如果像常规函数调用一样直接调用槽,则可能使用异常。这是因为直接调用槽时绕过了连接机制:

State state;
StateListener stateListener;// ...try {// OK; invoking slot directly.stateListener.throwException();
} catch (...) {qDebug() << "Handling exception not caught in slot.";
}

Exception Safety | Qt 5.15

相关文章:

  • 软件测试过程中用接口怎么将web系统的多页数据展示在1页
  • 罗盘时钟lua迷你世界
  • Parallels Desktop 19 for mac破解版安装激活使用指南
  • ArcgisEngine 释放内存案例
  • React 中的 ErrorBoundary
  • 数据分析:置换检验Permutation Test
  • 【JavaEE】Spring Web MVC详解
  • 【ajax核心05】宏任务与微任务
  • 【计算机网络】已解决:“‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件”报错
  • 2-14 基于matlab的GA优化算法优化车间调度问题
  • PMBOK® 第六版 管理项目知识
  • 如何使用Dockerfile创建容器映像
  • 解决WebStorm中不显示npm任务面板
  • JetBrains IDEA 新旧UI切换
  • Linux文本三剑客sed
  • [case10]使用RSQL实现端到端的动态查询
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Apache Spark Streaming 使用实例
  • co模块的前端实现
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • echarts的各种常用效果展示
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • mysql 5.6 原生Online DDL解析
  • MySQL-事务管理(基础)
  • nodejs调试方法
  • PHP 小技巧
  • Protobuf3语言指南
  • Vue全家桶实现一个Web App
  • XForms - 更强大的Form
  • 从零搭建Koa2 Server
  • 聚簇索引和非聚簇索引
  • 判断客户端类型,Android,iOS,PC
  • 普通函数和构造函数的区别
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 如何实现 font-size 的响应式
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • # linux从入门到精通(三)
  • # Panda3d 碰撞检测系统介绍
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #NOIP 2014#Day.2 T3 解方程
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (done) 声音信号处理基础知识(4) (Understanding Audio Signals for ML)
  • (JS基础)String 类型
  • (PySpark)RDD实验实战——求商品销量排行
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (备份) esp32 GPIO
  • (编译到47%失败)to be deleted
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (十三)MipMap
  • (文章复现)基于主从博弈的售电商多元零售套餐设计与多级市场购电策略