c++ - 如果 QObject 与信号和插槽一起使用,则替换异常

标签 c++ qt exception qt-signals

我试图将我的问题分解为一个小例子。真正的问题是更复杂的通信:

我有一个函数可以触发通信并连接服务器并将消息发送到服务器。如果有答案,客户端类会发出包含答案的信号。

void communicate()
{
     client.setUpMessage(); // the answer is emitted as a signal and
                            // and processed in the Slot 
                            // 'reactToAnswer(...)'

     client.sendMessage("HelloWorld");
}

void reactToAnswer(QString answer)
{
     parser.parseAnswer() // an error could occur
}

如果在处理响应的槽中检测到错误怎么办?我想停止函数 communicate() 的执行。这意味着不应再执行函数 client.sendMessage("HelloWorld")

出于天真,我试图用异常来处理这个问题:

void communicate()
{
     try
     {
          client.setUpMessage(); // the answer is emitted as a signal and
                                 // and processed in the Slot 
                                 // 'reactToAnswer(...)'

          client.sendMessage("HelloWorld");
      }
      catch(myException)
      {
           // do something
      }

void reactToAnswer(QString answer)
{
     if( !parser.parseAnswer() )
     {
          throw myException;
     }
}

这不起作用,从 qt 信号调用的插槽中抛出异常是未定义的行为。 usual way是重新实现QApplication::notify() resp。 QCoreApplication()::notify,但这对我不起作用。已经有一个用于 GUI 的 QApplication,我希望通信类 (QObject) 独立。所有的事情都应该在这个类中处理。

我希望我能全面地解释问题。我不想在任何情况下使用异常,其他停止通信的方式也适合我。

提前致谢!

最佳答案

我不确定您要完成的工作是否特别适合信号与槽范例……也许您只想使用常规的旧函数调用?即类似的东西:

void communicate()
{
   QString theAnswer;  // will be written to by setupMessage() unless error occurs
   if (client.setUpMessage(theAnswer)) 
   {
      reactToAnswer(theAnswer);     
      client.sendMessage("HelloWorld");
   }
}

信号和槽不适合的原因是信号被设计为可以同时连接到多个槽,并且槽方法被调用的顺序是未定义的——所以如果一个槽-method 试图以您描述的方式干扰信号发射过程,行为是相当不可预测的(因为您不知道有多少其他连接的插槽方法(如果有的话)已经作为信号的一部分被调用- emission,在你的特定插槽方法踩刹车之前)。当然,如果你曾经使用过排队/异步信号,那么它根本就不会工作,因为在信号发射函数已经返回很久之后,插槽将在完全不同的上下文中被调用。

就是说,如果您绝对必须为此使用信号和插槽,您可以让您的插槽发出它自己的错误发生信号,该信号可以连接回原始信号发射类中的插槽。然后该插槽可以设置一个 bool 值(或其他),然后您的 communicate() 方法可以检查该 bool 值的状态(就在 client.setUpMessage() 返回之后)以决定是继续执行还是提前返回。

(虽然我不推荐——信号和槽的存在是为了让你的程序不那么复杂,在这种情况下我认为使用它们而不是常规的函数调用实际上会让你的程序更复杂,没有相应的好处)

关于c++ - 如果 QObject 与信号和插槽一起使用,则替换异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43938284/

相关文章:

C++ 用常量值填充数组,循环和改变值

c++ - 如何防止在 Luabind 类中创建新属性?

c++ - 如何确定是从终端还是 GUI 运行

java - 为什么可以在 Java 中记录 OutOfMemory 错误?

java - 为什么没有选项可以使用自定义消息重新抛出异常?

c++ - 析构函数删除 main 中声明的动态数组

c++ - 为什么添加两个值在运行时有如此高的可变性?

c++ - 收集 2 : ld returned 1 exit status

c++ - 您可以将指针传递给 std::vector 的迭代器吗

java - Java 中的异常翻译与异常链接