类层次结构的Qt中的异常处理 [英] Exception Handling in Qt for Class Hierarchy

查看:243
本文介绍了类层次结构的Qt中的异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个用于Windows平台的Qt应用程序。我在类层次结构中使用异常处理时遇到问题。

I am working on developing a Qt application for windows platform. I am facing problem when using exception handling in class hierarchy.

我有一个B类对象在A类的函数中实例化。当由于某种原因,从B类抛出(而不是在B类中捕获)它没有被捕获在A类(相应的try-catch块存在于A类),而是应用程序崩溃显示一些窗口特定的错误。这种类型的类层次结构中的try-catch机制在Java中工作得很好。

I have Class B object instantiated in a function of Class A. When, due to some reason, an exception is thrown from Class B (and not caught in Class B) it is not being caught in Class A (appropriate try-catch block is present in Class A) and instead the application crashes showing some windows specific error. This type of try-catch mechanism in class hierarchy works perfectly fine in Java.

示例:

代表ClassB(Qt对话框)对象的ClassA代码片

This is piece of code of ClassA that is instatiating an object of ClassB (Qt Dialog)

void Class A::on_pbCallB_clicked()
{
    try
    {
        objClassB = new ClassB();
        objClassB->show();
    }
    catch(QString *strExceptionMsg)
    {
        QMessageBox::critical(this,"Error",*strExceptionMsg);
        exit(1);
    }
    catch(...)
    {
        QMessageBox::critical(this,"Error","Uknown Error");
        exit(1);
    }
}

当显示ClassB对话框并且对话框按下面的一段代码被调用:

When ClassB dialog is displayed and a button present on the dialog is pressed following piece of code is called:

void ClassB::on_pbThrowExp_clicked()
{
    try
    {
        throw (new QString("Throwing Exception !"));
    }
    catch(QString *strExceptionMsg)
    {
        throw strExceptionMsg;
    }
    catch(...)
    {
        throw (new QString("Unknown Error"));
    }
}

这会抛出在ClassB函数中捕获的异常,

This throws an exception which is caught in ClassB's function but when thrown further it is not caught in ClassA (From where objClassB is instantiated) and the entire application crashes.

我尝试了一个解决方案,其中我已经重新实现了QApplication的 notify 方法,其中,从应用程序中某处抛出的异常(如果未在任何地方捕获)在重新实现的通知方法中被捕获。但这样做并不会阻止应用程序关闭。

I have tried 1 solution where I have re-implemented QApplication’s notify method where, an exception thrown from somewhere in the application, if not caught anywhere, is being caught in re-implemented notify method. But doing this does not stop the application from closing down.

请确认这在Qt / C ++中是否可能,如果不是请指向一个替代方案这是一个老问题,但是由于仍然可能有人试图将Qt与异常结合起来(如果可能的话)在Qt。

Please confirm if this is even possible in Qt/C++ and if not please point me in direction of an alternative (if available) in Qt.

推荐答案

处理,以下是一个解决方案,为我工作。它需要c ++ 11支持。

This is an old question, but since there still might be people trying to combine Qt with exception handling, following is a solution that worked for me. It requires c++11 support though.

application.hpp:

application.hpp:

#ifndef APPLICATION_HPP
#define APPLICATION_HPP

#include <QApplication>
#include <exception>

///
/// This class catches any exceptions thrown inside proc()
/// and shows them using the message() function.
/// The virtual message() function can be overriden to customize
/// how the messages are shown. The default implementation
/// shows them using QMessageBox.
///
class Application: public QApplication
{
public:
    Application(int& argc, char* argv[]);
    bool notify(QObject* receiver, QEvent* event);

    virtual int proc() { return exec(); }
    int run();

    virtual int message(const std::string&);

private:
    std::exception_ptr _M_e = nullptr;
};

#endif // APPLICATION_HPP

application.cpp

application.cpp

#include "application.hpp"
#include <QMessageBox>

Application::Application(int& argc, char* argv[]):
    QApplication(argc, argv)
{ }

int Application::run()
{
    try
    {
        int code = proc();
        // Check if an exception was thrown and stored in Application::notify
        // and if so, rethrow it.
        if(_M_e) std::rethrow_exception(_M_e);

        return code;
    }
    catch(std::exception& e)
    {
        return message(e.what());
    }
}

int Application::message(const std::string& message)
{
    QMessageBox::critical(0, "Error", QString::fromStdString(message));
    return 1;
}

///
/// Qt does not allow exceptions thrown from event handlers
/// to be processed outside the event loop.
/// So we catch them here, store them in _M_e
/// and tell the application to exit.
///
bool Application::notify(QObject* receiver, QEvent* event)
{
    try
    {
        return QApplication::notify(receiver, event);
    }
    catch(...)
    {
        _M_e = std::current_exception();
        exit();
    }
    return false;
}

您可以使用 Application 运行函数而不是 exec / code>。 (或者,重命名运行 exec 隐藏 QApplication

You can use the Application class as you would the QApplication, except call the run function instead of exec. (Alternatively, rename run into exec to hide QApplication's exec.)

您可以覆盖消息功能来自定义错误消息。您还可以覆盖 proc 函数,以在 exec 之前/之后添加一些初始化/销毁代码。

You can override the message function to customize error messages. You can also override the proc function to add some initialization/destruction code before/after exec.

这篇关于类层次结构的Qt中的异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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