抛出异常后不执行 Catch 块调试语句?

Posted

技术标签:

【中文标题】抛出异常后不执行 Catch 块调试语句?【英文标题】:Catch Block Debug Statement not executing after an exception is thrown? 【发布时间】:2019-04-06 16:27:46 【问题描述】:

问题

我有一个派生自异常类 GlHelperException 的 GLSLFailedToLoadException。

GlHelperException 具有虚拟 throw 函数,以异常的标题属性和文件名的行号来描述错误。

但是当我在 main 函数中测试异常时,catch 块没有打印正确的 what() 函数调试日志,并在抛出 GLSLFailtedToLoadException 实例后返回终止调用。

异常定义


class GlHelperException: public std::exception
public:
    virtual const char* what() const throw()
        return (std::string(this->title) + 
        " - in file " + 
        std::string(this->filename) + 
        " at line " + 
        std::to_string(this->line)).c_str();    
    

protected:

    const char *title;
    const char *filename;
    int line;
;


class GLSLFailedToLoadException: public GlHelperException
public:
    GLSLFailedToLoadException(const char *filename, int line);
;


GLSLFailedToLoadException::GLSLFailedToLoadException(const char *filename, int line)
    this->filename = filename;
    this->line = line;
    this->title = "Failed to load and compile GLSL program ";

测试投掷地点



int main(int argc, char **argv)
/* Irrelevant Code*/

    try
        throw new GLSLFailedToLoadException(__FILE__, __LINE__);
    
    catch(GLSLFailedToLoadException &e)
        std::cout<<"Exception Caught"<<std::endl;
        std::cout<<e.what()<<std::endl;
    
    return 0;


实际结果

terminate called after throwing an instance of 'GLSLFailedToLoadException*'
Aborted (core dumped)

预期结果

Failed to load and compile GLSL program in __FILE__ at __LINE__

【问题讨论】:

在您的GLSLFailedToLoadException 构造函数中,您真的 应该使用初始化列表而不是构造函数主体。然后将您的const char * 成员更改为const std::strings,这样您就可以真正复制传入的值,而不仅仅是存储即将失效的指针。 【参考方案1】:

您正在抛出一个指向对象的指针,但试图捕获一个对象(通过引用)。

更改您的 throw 语句以抛出一个对象:

throw GLSLFailedToLoadException(__FILE__, __LINE__);

我还建议始终通过const 引用catch 异常,所以:

catch (const GLSLFailedToLoadException& e)

由于您的代码当前正在编写,您未能捕获异常并因此离开main(),从而导致您看到的结果 - 未捕获的异常终止程序。

您还需要在您的异常对象中使用std::strings 而不是指针 (const char *),因为您当前存储的指针在对象的持续时间内不存在,因此您需要复制指向的到字符串。

【讨论】:

但是现在输出是异常捕获 调试日志未打印 @SiddharthSingh :将 const char *title;const char *filename; 更改为 std::string。你不能只存储这些指针。 @SiddharthSingh 这是一个完全不同的问题,应该保证一个不同的问题。但是,您创建了一个 临时 std::string 对象,该对象立即被破坏,这意味着您返回的指针立即变得无效。 @SiddharthSingh 为了扩展 Jesper Juhl 指出的问题,不要将指针作为成员存储在对象中,而是在构造函数中构造完整的字符串并将其存储(作为 std::string 对象) .由于字符串存储在对象中,指向它的指针(及其包含的原始字符串)在异常对象的整个生命周期内都是有效的。

以上是关于抛出异常后不执行 Catch 块调试语句?的主要内容,如果未能解决你的问题,请参考以下文章

C#中如何处理异常?怎么使用try-catch语句?

java中 在一个异常处理中啥语句块是可多个的

php try catch 捕获哪些错误

JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗

JAVA异常处理

如果在 catch 块中抛出异常,是不是会执行 finally 块? [复制]