当我捕获异常时,我想发出一个信号并将该异常传递给一个插槽,以便可以在另一个线程中处理它。信号和插槽使用Qt:QueuedConnection类型连接。
我首先尝试过这个:
/*in .h*/
signals:
void exceptionOccured(const std::exception &e);
public slots:
void exceptionReceive(const std::exception &e);
/*in .cpp*/
connect(this,SIGNAL(exceptionOccured(const std::exception&)),this,SLOT(exceptionReceive(const std::exception&)),Qt::QueuedConnection);
try {
throw std::runtime_error("test");
} catch (std::exception &e) {
emit exceptionOccured(e);
}
这有点起作用,但是当QT将引用的对象的副本放在队列中时,exceptionReceived插槽接收std :: exception类型对象,并且所有其他信息都将丢失。
然后我尝试将指针传递给原始异常对象,但这给我的问题是,当调用插槽时,实际对象已经消失。
如何告诉QT制作异常的正确副本(实际应用程序具有std :: exception的多级继承)或将catch'ed异常转换为某种安全指针类型(即从中复制它)堆栈到堆等)。
P.S。 该对象将消息发送给自己,因为try / catch语句是使用QtConcurrent :: run()从lambda函数运行的;
答案 0 :(得分:0)
如果你坚持使用基本异常类型,那么这是一个C ++问题,而不是Qt问题。您需要实现某种类型的虚拟副本构造函数模式。一旦你这样做,Qt将自动做正确的事情。
一种这样的模式:
class clonable_exception : public std::exception {
protected:
virtual void clone_to(clonable_exception& dst) const = 0;
public:
clonable_exception() = default;
clonable_exception(const clonable_exception& src) {
src.clone_to(*this);
}
clonable_exception & operator=(const clonable_exception& src) {
src.clone_to(*this);
}
};
所有信号和广告位均应使用clonable_exception
类型而非std::exception
。
答案 1 :(得分:0)
std::exception_ptr
被添加到标准的C ++ 11中。 std::current_exception()
让你获得当前异常的句柄,然后你可以传递它并在你想要的任何线程中重新抛出它。