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

时间:2018-07-30 15:09:03

标签: c++ qt visual-c++ exception-handling 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();
}

cameraWorkerThread变得相当混乱,并终止于RaGaCCMainView的析构函数中:

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还是有其他可行的解决方案?

我一直感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

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

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

理想情况下,您应该对代码进行结构化,以免调用从析构函数生成异常的代码。