通过QT的signal / slot系统作为参数传递泛型异常

时间:2015-09-05 10:05:58

标签: c++ multithreading qt c++11 polymorphism

当我捕获异常时,我想发出一个信号并将该异常传递给一个插槽,以便可以在另一个线程中处理它。信号和插槽使用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函数运行的;

2 个答案:

答案 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()让你获得当前异常的句柄,然后你可以传递它并在你想要的任何线程中重新抛出它。

http://en.cppreference.com/w/cpp/error/exception_ptr的详细信息。