简体   繁体   English

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

[英]Is there any possibility to throw an exception when emitting a Qt signal?

While reviewing some code, I found a piece of code like that: 在查看一些代码时,我发现了一段类似的代码:

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!";
   }
}

Is there any possibility to enter on the catch here? 这里有没有可能进入渔获? As far as I know, there are no possible exception being thrown: emit is just a macro to create a table to call the appropriate functions connected to that signal on the *.moc file . 据我所知,没有引发异常的可能: 发出只是一个宏,用于创建表以调用连接到* .moc文件上该信号的适当函数 Is that try catch really needed? 那真的很需要尝试吗?

Yes, the catch is needed in your example, at least if any slots connected to fooSignal throw an std::exception . 是的,在您的示例中,至少在连接到fooSignal任何插槽抛出std::exception ,都需要使用catch。

The statement emit fooSignal(); 该语句emit fooSignal(); calls all connected slots synchronously. 同步调用所有连接的插槽。 Basically QObject internally has a connection table in which it stores all connections for an object, which each slot being a function pointer. 基本上, QObject内部有一个连接表,其中存储了一个对象的所有连接,每个插槽都是一个函数指针。 Basically what emit does (or rather, what the moc-generated implementation of fooSignal does) is that it simply iterates over the connection table and calls all function pointers for each connected slot. 本质上来说, emit所做的事情(或者更确切地说,是由moc生成的fooSignal实现)所做的是,它简单地遍历了连接表并为每个连接的插槽调用了所有函数指针。

So the slots are called from within the connect statement. 所以槽从连接语句调用。 That also means if any slots throw an exception, the exception will propagate outside of the emit statement. 这也意味着,如果有任何插槽抛出异常,则该异常将传播到emit语句之外。

Note that the internal moc-generated code for fooSignal is only exception-safe as of recent, see Olivier's answer on this bug report . 请注意,内部的fooSignal moc生成代码fooSignal才是异常安全的,请参阅此错误报告中 Olivier的回答。 That means older versions of Qt can't deal with exceptions being thrown in slots, and the moc-generated code will fail in undefined ways if slots throw an exception. 这意味着较早版本的Qt无法处理在插槽中引发的异常,并且如果插槽引发异常,moc生成的代码将以未定义的方式失败。

EDIT: I also want to add that having slots that throw exceptions is bad practice, try avoiding that. 编辑:我还想补充一下,有抛出异常的插槽是一种不好的做法,请尝试避免这种情况。 The code that calls emit doesn't know what slots are connected, so it doesn't know what exceptions it needs to catch. 调用emit的代码不知道连接了哪些插槽,因此也不知道需要捕获哪些异常。 Furthermore, as soon as you have queued connections instead of direct connections, the slots will be called asynchronously instead of synchronously, and you won't be able to catch the slots' exceptions. 此外,一旦您将连接而不是直接连接排入队列,插槽将被异步调用而不是同步调用,您将无法捕获插槽的异常。

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

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