Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КП - 2 часть - Лекция 2. Исключительные ситуаци...docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
342.41 Кб
Скачать

1. Хочется, чтобы приложение как можно быстрее упало и не успело сделать ничего плохого.

#include "stdafx.h"

#include <stdio.h>

#include <errno.h>

#include <string.h>

FILE* OpenFileRead(const char* fileName)

{

FILE *ptr_file = fopen(fileName, "r");

if (!ptr_file)

throw 13;

return ptr_file;

}

int main()

{

FILE *ptr_file = OpenFileRead("output.txt");

// ...

fclose(ptr_file);

return 0;

}

throw завершит приложение сразу же. Ни одна инструкция больше не выполнится.

2. Хочется, чтобы перед своей кончиной приложение напечатало нечто, позволяющее понять, что не так.

// Вариант с кодом ошибки

#include "stdafx.h"

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <iostream>

using namespace std;

FILE* OpenFileRead(const char* fileName)

{

FILE *ptr_file = fopen(fileName, "r");

if (!ptr_file)

throw 13;

return ptr_file;

}

int main()

{

try

{

FILE *ptr_file = OpenFileRead("output.txt");

// ...

fclose(ptr_file);

}

catch (int errorCode)

{

cerr << "Приложение упало с кодом ошибки " << errorCode

<< ". Приносим извинения за доставленные неудобства. Обратитесь в слжубу поддержки по телефону 1234544.\n";

return 1;

}

return 0;

}

Как видите, на самом верхнем уровне добавился блок по отлавливанию исключений. В качестве исключений можно бросать какие-то данные, затем их ловить и перед завершением приложения показывать пользователю. Код при этом остается компактным.

// Вариант с текстовым сообщением.

#include "stdafx.h"

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <iostream>

using namespace std;

FILE* OpenFileRead(const char* fileName)

{

FILE *ptr_file = fopen(fileName, "r");

if (!ptr_file)

throw "Failed to open input file";

return ptr_file;

}

int main()

{

try

{

FILE *ptr_file = OpenFileRead("output.txt");

// ...

fclose(ptr_file);

}

catch (const char* errorMessage)

{

cerr << "Ошибка: " << errorMessage << "\n";

return 1;

}

return 0;

}

В качестве исключения стали бросать строки и другие данные, которые могли легко идентифицировать ошибку.

3. Хочется, чтобы в качестве исключения был отдельный тип данных. В котором было бы некоторое строковое представление произошедшей проблемы и любая дополнительная информация, которая поможет ее идентифицировать.

#include "stdafx.h"

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <iostream>

#include <exception>

#include <string>

#include <sstream>

using namespace std;

class IOException : public exception

{

private:

string m_message;

public:

IOException(const char* message, int errorCode)

{

stringstream ss;

ss << message << ". Error code: " << errorCode << ".";

m_message = ss.str();

}

virtual const char* what() const

{

return m_message.c_str();

}

};

FILE* OpenFileRead(const char* fileName)

{

FILE *ptr_file = fopen(fileName, "r");

if (!ptr_file)

throw IOException("Failed to open input file", errno);

return ptr_file;

}

int main()

{

try

{

FILE *ptr_file = OpenFileRead("output.txt");

// ...

fclose(ptr_file);

}

catch (const exception& exception)

{

cerr << "Ошибка: " << exception.what() << "\n";

return 1;

}

return 0;

}

Завели класс exception, который получает в конструкторе текст ошибки, имеет виртуальный метод what(), который возвращает этот текст во внешний мир. В примере выше был сделан наследник от класса, который добавляет дополнительную информацию. Он выводит не только текст, но и код ошибки. Как видите, отлавливание ошибок ловит как исключения базового класса, так и его наследников.

К сожалению старые подходы с бросанием различных типов данных оставили (кроме экземпляров exception и наследников от него), поскольку развитие С++ происходит исключительно методом расширения языка..., чтобы написанный ранее код мог продолжать компилироваться.