繁体   English   中英

通过QT的信号/插槽系统传递通用异常作为参数

[英]Pass generic exception through QT's signal/slot system as argument

当我捕获到异常时,我想发出信号并将该异常传递到插槽,以便可以在其他线程中处理它。 信号和插槽使用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异常转换为某种安全的指针类型(即,将其从堆栈复制到堆左右)。

PS该对象向自身发送消息,因为try / catch语句是使用QtConcurrent :: run()从lambda函数运行的;

如果您坚持使用基本异常类型,那么这是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

为了完全解决此问题,将std::exception_ptr添加到标准的一个C ++ 11中。 std::current_exception()使您可以获取当前异常的句柄,然后可以将其传递并重新放入所需的任何线程中。

有关详细信息,请参见http://en.cppreference.com/w/cpp/error/exception_ptr

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM