C++/Qt - 析构函数中出现异常 -> 已调用中止
C++/Qt - Exception in destructor -> abort has been called
简介
MSVC 2017 64 位,Win 10 64 位,Qt Creator
我有一个 class CameraControl
建立到相机的连接并且是 QMainWindow
class:
的数据成员
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
),主视图就会退出。为了在用户决定关闭主 window 时以一种很好的方式结束相机连接,我调用了一个函数 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。
然而,当我关闭主 window w
并抛出异常时,我从 msvc 收到一条 abort() has been called
消息:
当然我不知道这里有什么问题。我建议这个问题与工作线程的处理有关...
我希望异常被忽略(或者这也是对预期行为的误解?)
问题
- 是什么导致了这个问题?
- 我需要使用
try
和 catch
还是有其他可行的解决方案?
非常感谢您的帮助。
您的链接回答指出,您 应该捕获并删除您从析构函数调用的代码中的异常,而不是重新抛出它们。
默认情况下,析构函数中未处理的异常不会被忽略,并且会导致从内存泄漏到崩溃的各种问题。任何可能从析构函数中抛出异常的代码都应包装在 try
/catch
中,并在可能的情况下处理由此产生的异常(例如通过写入日志消息)或完全忽略。
理想情况下,您应该构建代码,这样您就不会从析构函数中调用异常生成代码。
简介
MSVC 2017 64 位,Win 10 64 位,Qt Creator
我有一个 class CameraControl
建立到相机的连接并且是 QMainWindow
class:
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
),主视图就会退出。为了在用户决定关闭主 window 时以一种很好的方式结束相机连接,我调用了一个函数 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。
然而,当我关闭主 window w
并抛出异常时,我从 msvc 收到一条 abort() has been called
消息:
当然我不知道这里有什么问题。我建议这个问题与工作线程的处理有关...
我希望异常被忽略(或者这也是对预期行为的误解?)
问题
- 是什么导致了这个问题?
- 我需要使用
try
和catch
还是有其他可行的解决方案?
非常感谢您的帮助。
您的链接回答指出,您 应该捕获并删除您从析构函数调用的代码中的异常,而不是重新抛出它们。
默认情况下,析构函数中未处理的异常不会被忽略,并且会导致从内存泄漏到崩溃的各种问题。任何可能从析构函数中抛出异常的代码都应包装在 try
/catch
中,并在可能的情况下处理由此产生的异常(例如通过写入日志消息)或完全忽略。
理想情况下,您应该构建代码,这样您就不会从析构函数中调用异常生成代码。