我应该抓住它 [英] Where am I supposed to catch it

查看:162
本文介绍了我应该抓住它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我像这样连接信号到插槽:

  connect(thread,SIGNAL (计数())); 

并且计数可以抛出异常,我应该在哪里it?

我应该做:

  try 
{
connect (thread,SIGNAL(starts()),engine,SLOT(count()));
}
catch(const X& e)
{
}


解决方案


我应该捕捉它吗?


这正是为什么Qt不支持跨信号/槽连接抛出异常。如果您尝试它,您会看到以下消息:


Qt已捕获到从事件处理程序抛出的异常。在Qt中不支持从事件处理程序抛出
异常。您必须
重新实现QApplication :: notify()并捕获所有异常。


子类QApplication和捕捉你的异常那里,但这将是一个非常讨厌的方式处理的东西。



如果可能,我建议重写计数,使其不抛出。






如果无法重写count(),该怎么办?
$ b

例如,如果count()是您使用的第三方库中的函数的一部分呢?



否插槽在任何官方的Qt库抛出,所以如果你使用的第三方库有一个插槽,抛出,这可能是一个迹象,它不是一个好的库。如果你想使用它,无论如何,我建议,而不是捕捉它 QApplication :: notify ,你改为创建一个适配器。



这是什么意思?首先创建一个对象,在构造函数中接受您的粗略的第三方对象。在其中,写一个插槽,用try / catch块调用抛出槽。



以这种方式捕获异常会将相关代码保持在一起,并阻止 QApplication :: notify 从一堆无关的try / catch块填充,如果你遇到多个这些有问题的函数。



例如:

  class BadCounter {
Q_OBJECT
public slots:
void count(){throw CounterError(unable to count); }
};

class CounterAdaptor {
Q_OBJECT
BadCounter * counter_;
public:
CounterAdaptor(BadCounter * counter){
counter_ = counter;
}
public slots:
void count(){
try {
counter _-> count();
} catch(const CounterError& e){
std :: cerr<< e.what()< std :: endl;
}
}
};

int main(){
BadCounter engine;
CounterAdaptor适配器(& engine);
QThread * thread = new QThread();
connect(thread,SIGNAL(started()),& adapter,SLOT(count()));
thread.start();
... // etc ...
delete thread;
}






你想处理可以从任何地方抛出的东西?



这种全局关注的一个明显的例子是意外的异常。错误可以发生在任何地方。希望记录尽可能多的关于事件的细节,以便可以识别和纠正原因。在这种情况下,您想要在您自己的子类中重新实现 QApplication :: notify ,如 jichi的回答。使用全局处理程序来处理全局问题是相当合理的。


if I connect signal to slot like this:

connect(thread,SIGNAL(started()),engine,SLOT(count()));  

and the count can throw exception, where (in which place of the code) am I supposed to catch it?
Am I supposed to do:

try
{
connect(thread,SIGNAL(started()),engine,SLOT(count()));  
}
catch(const X& e)
{
}

解决方案

where am I supposed to catch it?

This is exactly why Qt does not support throwing exceptions across signal/slot connections. If you try it, you'll see this message:

Qt has caught an exception thrown from an event handler. Throwing exceptions from an event handler is not supported in Qt. You must reimplement QApplication::notify() and catch all exceptions there.

As it mentions, it is possible to subclass QApplication and catch your exception there, but that will be a very annoying way of handling things.

If possible, I would recommend rewriting count such that it does not throw.


What if you can't rewrite count()?

For example, what if count() is part of a function in a 3rd-party library that you're using?

No slot in any official Qt library throws, so if you're using a third-party library with a slot that throws, it's probably a sign that it's not a good library. If you want to use it anyway, I recommend that rather than catching it in QApplication::notify, that you instead create an adapter.

What does that mean? First create an object that takes in your sketchy third-party object in the constructor. In it, write a slot that wraps a call to the throwing slot with a try/catch block. Now instead of connecting to the sketchy third-party object's slot, connect to your newly create object's slot.

Doing the exception catching this way keeps related code together, and prevents QApplication::notify from filling up with a bunch of unrelated try/catch blocks if you encounter more than one of these problematic functions.

For example:

class BadCounter {
Q_OBJECT
public slots:
  void count() { throw CounterError("unable to count"); }
};

class CounterAdaptor {
Q_OBJECT
  BadCounter* counter_;
public:
  CounterAdaptor(BadCounter* counter) {
    counter_ = counter;
  }
public slots:
  void count() {
    try {
      counter_->count();
    } catch (const CounterError& e) {
      std::cerr << e.what() << std::endl;
    }
  }
};

int main() {
  BadCounter engine;
  CounterAdaptor adaptor(&engine);
  QThread* thread = new QThread();
  connect(thread,SIGNAL(started()),&adaptor,SLOT(count())); 
  thread.start();
  ... // etc...
  delete thread;
}


What if you want to handle something that could be thrown from anywhere?

The obvious example of this sort of global concern is an unexpected exception. Mistakes can happen anywhere. It would be desirable to log as many details about the event as possible so the cause could be identified and corrected. In this case, you would want to reimplement QApplication::notify in your own subclass as shown in jichi's answer. Using a global handler for global concerns is quite reasonable.

这篇关于我应该抓住它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆