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();
}
Я думал, что это не будет проблемой, потому что брошенные вещи в деструкторах игнорируются тем не мение.
Однако, когда я закрываю главное окно w
и исключение брошено, я получаю abort() has been called
сообщение от msvc:
Конечно, я понятия не имею, в чем здесь проблема. Я бы предположил, что эта проблема связана с обработкой рабочего потока …
Я хотел бы, чтобы исключение было проигнорировано, как это должно быть (или это тоже неправильное понимание предполагаемого поведения?)
try
а также catch
или есть другое жизнеспособное решение?Я всегда ценю вашу помощь.
Ваш связанный ответ утверждает, что вы должен ловить и отбрасывать исключения из кода, который вы вызываете из деструктора, а не перебрасывать их.
По умолчанию необработанные исключения в деструкторах практически не игнорируются и будут вызывать проблемы, варьирующиеся от утечек памяти до сбоев. Любой код, который может вызвать исключение из деструктора, должен быть заключен в try
/catch
и возникающее исключение обрабатывается, если это возможно (например, путем записи сообщения журнала), или просто полностью игнорируется.
В идеале вы должны структурировать свой код так, чтобы не вызывать код, генерирующий исключение, из деструкторов.
Других решений пока нет …