发射Qt信号时是否有可能抛出异常?

Ian*_*ros 2 c++ qt

在查看一些代码时,我发现了一段代码:

struct MyFooStructure
{
  //Nothing unusual, just basic types
}

class Foo : public QObject
{
   Q_Object

public:
   void fooMethod(const MyStructure &s);

signals:
   void fooSignal(const MyStructure &);
}

void Foo::fooMethod(const MyStructure &s)
{
   try
   {
      emit fooSignal(s)
   }
   catch(const std::exception &e)
   {
      qDebug() << "An exception!";
   }
}
Run Code Online (Sandbox Code Playgroud)

有没有可能进入这里的渔获?据我所知,没有抛出可能的异常:emit只是一个宏来创建一个表来调用连接到*.moc文件上的那个信号的相应函数.这是尝试抓住真的需要吗?

Tho*_*ire 6

是的,在你的例子中需要捕获,至少如果连接的任何插槽fooSignal抛出一个std::exception.

该语句emit fooSignal();同步调用所有连接的插槽.基本上QObject内部有一个连接表,它在其中存储对象的所有连接,每个插槽都是一个函数指针.基本上是什么emit(或者更确切地说,moc生成的实现是什么fooSignal)是它简单地遍历连接表并为每个连接的槽调用所有函数指针.

所以时隙均称为连接语句.这也意味着如果任何槽抛出异常,异常将在emit语句之外传播.

请注意,内部moc生成的代码fooSignal仅是最近的异常安全,请参阅Olivier 对此错误报告的回答.这意味着旧版本的Qt无法处理插槽中抛出的异常,如果插槽抛出异常,则moc生成的代码将以未定义的方式失败.

编辑:我还想补充说,拥有抛出异常的插槽是不好的做法,试着避免这种情况.调用的代码emit不知道连接的是什么插槽,因此它不知道需要捕获哪些异常.此外,只要您具有排队连接而不是直接连接,就会异步调用插槽而不是同步调用插槽,并且您将无法捕获插槽的异常.