在查看一些代码时,我发现了一段代码:
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文件上的那个信号的相应函数.这是尝试抓住真的需要吗?
是的,在你的例子中需要捕获,至少如果连接的任何插槽fooSignal抛出一个std::exception.
该语句emit fooSignal();同步调用所有连接的插槽.基本上QObject内部有一个连接表,它在其中存储对象的所有连接,每个插槽都是一个函数指针.基本上是什么emit(或者更确切地说,moc生成的实现是什么fooSignal)是它简单地遍历连接表并为每个连接的槽调用所有函数指针.
所以时隙均称为内连接语句.这也意味着如果任何槽抛出异常,异常将在emit语句之外传播.
请注意,内部moc生成的代码fooSignal仅是最近的异常安全,请参阅Olivier 对此错误报告的回答.这意味着旧版本的Qt无法处理插槽中抛出的异常,如果插槽抛出异常,则moc生成的代码将以未定义的方式失败.
编辑:我还想补充说,拥有抛出异常的插槽是不好的做法,试着避免这种情况.调用的代码emit不知道连接的是什么插槽,因此它不知道需要捕获哪些异常.此外,只要您具有排队连接而不是直接连接,就会异步调用插槽而不是同步调用插槽,并且您将无法捕获插槽的异常.
| 归档时间: |
|
| 查看次数: |
882 次 |
| 最近记录: |