Оператор отладки Catch Block не выполняется после возникновения исключения?

#c #linux #c 11 #g

#c #linux #c 11 #g

Вопрос:

Проблема

У меня есть GLSLFailedToLoadException, которое является производным от класса исключений GlHelperException.

GlHelperException имеет функцию виртуального броска для описания ошибки с помощью свойства title исключения и номера строки с именем файла.

Но когда я тестирую исключение в основной функции, блок catch не печатает правильный журнал отладки функции what() и возвращает terminate, вызванный после создания исключения 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 amp;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__
  

Комментарии:

1. В вашем GLSLFailedToLoadException конструкторе вам действительно следует использовать список инициализации, а не тело конструктора. Также затем измените свои const char * члены на const std::string s, чтобы вы фактически делали копию переданных значений, а не просто сохраняли указатели, которые вот-вот станут недействительными.

Ответ №1:

Вы создаете указатель на объект, но пытаетесь перехватить объект (по ссылке).

Измените свой throw оператор, чтобы создать объект:

 throw GLSLFailedToLoadException(__FILE__, __LINE__);
  

Я бы также рекомендовал всегда делать catch исключения по const ссылке, поэтому:

 catch (const GLSLFailedToLoadExceptionamp; e)
  

Поскольку ваш код в данный момент написан, вам не удается перехватить исключение, и оно, таким образом, уходит main() , в результате чего вы видите результат — неперехваченное исключение, завершающее программу.

Вам также необходимо использовать std::string s в вашем объекте исключения вместо указателей ( const char * ), потому что указатели, которые вы храните в данный момент, не сохраняются в течение всего срока действия объекта, поэтому вам нужно сделать копии строк, на которые указано.

Комментарии:

1. Но теперь на выходе получается пойманное исключение

2. Журнал отладки не печатается

3. @SiddharthSingh : Изменить const char *title; и const char *filename; быть std::string . Вы не можете просто хранить эти указатели.

4.@SiddharthSingh Это совершенно другая проблема, которая должна требовать другого вопроса. Однако вы создаете временный std::string объект, который немедленно уничтожается, что означает, что возвращаемый вами указатель немедленно становится недействительным.

5. @SiddharthSingh Чтобы расширить проблему, на которую указал Джеспер Юл, вместо того, чтобы хранить указатели как члены в объекте, создайте полную строку в конструкторе и сохраните ее (как std::string объект). Поскольку строка хранится в объекте, указатели на нее (и содержащуюся в ней необработанную строку) будут действительны на протяжении всего срока службы объекта исключения.