C++/Qt - 析构函数中出现异常 -> 已调用中止

标签 c++ qt visual-c++ exception worker-thread

简介

MSVC 2017 64 位,Win 10 64 位,Qt Creator

我有一个 CameraControl 类,它建立与相机的连接并且是 QMainWindow 类的数据成员:

class RaGaCCMainView : public QMainWindow
{
        Q_OBJECT
    ...

    public:
        explicit RaGaCCMainView(QWidget *parent = nullptr);
        ~RaGaCCMainView();

    private:
        CameraControl cameraControl;
        QThread cameraWorkerThread;
        ...

    ...
};

class CameraControl : public QObject
{
        Q_OBJECT
    ...

    public:
        explicit CameraControl(QObject *parent = nullptr);
        ~CameraControl();
        void stopImageAcquisition();
        ...

    ...
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    RaGaCCMainView w;
    w.setAttribute(Qt::WA_QuitOnClose);
    w.show();

    return a.exec();
}

CameraControl 被移动到 cameraWorkerThread:

RaGaCCMainView::RaGaCCMainView(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::RaGaCCMainView)
{
    ...

    this->cameraControl.moveToThread(&(this->cameraWorkerThread));

    // Object should be deletable after the thread finished!
    this->connect(&this->cameraWorkerThread, &QThread::finished, &this->cameraControl, &QObject::deleteLater);

    ... // some connects

    this->cameraWorkerThread.start();
}

cameraWorkerThreadRaGaCCMainView 的析构函数中被退出和终止:

RaGaCCMainView::~RaGaCCMainView()
{
    this->cameraWorkerThread.quit();
    this->cameraWorkerThread.terminate();
    delete this->ui;
}

如您所见,如果用户关闭主视图,主视图将退出 (Qt::WA_QuitOnClose)。为了在用户决定关闭主窗口时以一种很好的方式结束相机连接,我调用了一个函数 stopImageAcquisition 来处理一些相机内容(停止获取图像)并可能引发异常:

CameraControl::~CameraControl()
{
        this->stopImageAcquisition(); // Here an exception could/will be thrown!
        USB1_3M_CloseCamera(this->cameraHandle);
        USB1_3M_TerminateLibrary();
}

问题

我认为这不会有任何问题,因为 thrown things in destructors get ignored无论如何。

然而,当我关闭主窗口 w 并抛出异常时,我从 msvc 收到一条 abort() has been called 消息:

enter image description here

当然,我不知道这里的问题是什么。我建议这个问题与工作线程的处理有关...

我希望异常被忽略(或者这也是对预期行为的误解吗?)

问题

  1. 是什么导致了这个问题?
  2. 我需要使用 trycatch 还是有其他可行的解决方案?

我一直很感激你的帮助。

最佳答案

您的链接答案指出,应该从您从析构函数调用的代码中捕获并删除异常,而不是重新抛出它们。

默认情况下,析构函数中未处理的异常不会被忽略,并且会导致从内存泄漏到崩溃的各种问题。任何可能从析构函数中抛出异常的代码都应该包装在 try/catch 中,并在可能的情况下处理由此产生的异常(例如,通过编写日志消息)或者只是完全忽略。

理想情况下,您应该构建代码,这样您就不会从析构函数中调用异常生成代码。

关于C++/Qt - 析构函数中出现异常 -> 已调用中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51597070/

相关文章:

c++ - 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?

c++ - 如何将 Visual Studio 项目导出到 Qt?

c++ - 在父类(super class)中重载运算符,但子类声称它已经定义

matlab - 如何使用 Visual Studio 2010 调试 MATLAB .mex32/.mex64 文件

c++ - 无法在 Qt Widget 上绘制,显示错误 "paintEngine: Should no longer be called"

C++ 预处理器标准行为

c++ - 外部变量导致多重定义错误

c++ - 任意长度的 BINARY 类型的 QT SQL 数据类型 (QVariant) 映射

c++ - 导出静态库的成员函数

multithreading - 从另一个线程读取Qt小部件可以吗?