Приведение типов. Механизм исключений. Задача на разбор командной строки

Содержание

Слайд 2

Содержание Исключения Исключения в конструкторах и деструкторах Операторы приведения типов Постановка

Содержание

Исключения
Исключения в конструкторах и деструкторах
Операторы приведения типов
Постановка задачи: разбор аргументов командной

строки
Описание базового класса переменной
Описание произвольной переменной
Менеджер переменных
Слайд 3

Исключения Механизм исключений Регламентирует редко случающиеся ситуации, влекущие радикальные изменения в

Исключения

Механизм исключений
Регламентирует редко случающиеся ситуации, влекущие радикальные изменения в текущем поведении

программы либо прекращение ее работы
Код, генерирующий исключения
Помещается в блок try { }
Исключения создаются вызовом throw [exception_object];
Код, обрабатывающий исключения
Помещается в блок catch {}
Слайд 4

Объекты-исключения Семантика Данные об ошибке std::exception Базовый класс исключения в стандартной

Объекты-исключения

Семантика
Данные об ошибке
std::exception
Базовый класс исключения в стандартной библиотеке
Все исключения стд. библиотеки

наследованы от std::exception
Объекты-исключения
В качестве объекта-исключения может выступать любой класс
Классы исключений могут быть организованы в иерархию

try
{
m_task_desc->memory.h_pinned_memmgr.reset(new mem_ops::memory_manager_pinned);
}
catch (const std::exception &e)
{
LOG_STREAM << "[ERROR] Pinned memory exception occured: ";
LOG_STREAM << e.what();
LOG_STREAM << "Pinned memory manager will be reset to NULL. \n";
m_task_desc->memory.h_pinned_memmgr.reset();
}

Слайд 5

Обработка исключений catch блоки обрабатываются в порядке объявления catch (…) {

Обработка исключений

catch блоки обрабатываются в порядке объявления
catch (…) { }
Ловит любое

исключение
Должен быть объявлен последним
catch (BaseClass &b)
Должен быть объявлен после всех наследников
Слайд 6

Обработка исключений Обработка исключения = развертка стека вызовов При возникновении исключения

Обработка исключений

Обработка исключения = развертка стека вызовов
При возникновении исключения поиск обработчика

заканчивается во внешнем блоке try .. catch, в который «обернут» main (winmain)
Попадание в этот блок ведет к вызову функции terminate()
Возникновение исключения во время развертки стека = вызов terminate()
Слайд 7

Исключения в конструкторах и деструкторах Исключение в конструкторе Объект не является

Исключения в конструкторах и деструкторах

Исключение в конструкторе
Объект не является созданным, и

тело деструктора не будет вызвано
Деструкторы предков и полей вызываются в стандартном порядке
Исключение в деструкторе
При возникновении на этапе развертки стека вызовов приведет к вызову terminate()
Следует избегать ОБА ВАРИАНТА использования исключений
Слайд 8

Операторы приведения типов type_to_cast a = static_cast (b); Приведение объекта b

Операторы приведения типов

type_to_cast a = static_cast (b);
Приведение объекта b к

типу type_to_cast
Проверка уровня компиляции
type_to_cast *a = dynamic_cast (b);
Используется для приведения типов с проверкой в run-time (RTTI, run-time type info)
При неудаче вернет NULL
type_to_cast &a = dynamic_cast (b);
В случае ошибки порождает исключение std::bad_cast
const_cast
Снимает модификаторы const и volatile
reinterpret_cast
Максимально небезопасное приведение типов
Конвертация указателя в int, любого типа в любой другой
Слайд 9

Ассоциативный контейнер map std::map Отсортированная структура данных, состоящая из пар ключ-значение

Ассоциативный контейнер map

std::map
Отсортированная структура данных, состоящая из пар ключ-значение
Реализует красно-черное дерево
Тип

«ключа» должен иметь оператор сравнения
Операции (ключ = std::string)
Объявление std::map mymap;
Добавление mymap[“firstVal”] = 10;
Поиск
std::map::iterator – тип итератора по контейнеру
std::map::iterator it = mymap.find(“firstVal”);
it == mymap.end() – верно в случае отсутствия элемента в контейнере
Слайд 10

Разбор аргументов командной строки Параметры ком. строки Пара «имя» «значение» Значение

Разбор аргументов командной строки

Параметры ком. строки
Пара «имя» «значение»
Значение может быть произвольного

типа
Значение считывается из строки
Задача: разработать класс для обработки командной строки
Регистрация имени новой переменной
Установка значения по умолчанию для переменной
Возврат значения по имени переменной
Заполнение значений переменных по массиву argV и кол-ву аргументов argC
Слайд 11

Класс переменной Пара «имя» - «значение» Переменная = значение Класс переменной

Класс переменной

Пара «имя» - «значение»
Переменная = значение
Класс переменной
Унифицированный интерфейс для хранения

значения любого типа
Интерфейс для извлечения значения любого типа из строки
Слайд 12

Базовый класс переменной Любой унифицированный интерфейс = базовый класс class variable_base

Базовый класс переменной

Любой унифицированный интерфейс = базовый класс

class variable_base
{
public:
/*!
*

\brief A method for extracting a value from string.
* \param var_string String with value to extract
* \return true if parsing was successful
*/
virtual bool set_value(const std::string& var_string) = 0;
};
Слайд 13

Класс переменной: реализация template class variable: public variable_base { public: variable(const

Класс переменной: реализация

template
class variable: public variable_base
{
public:
variable(const T& init_value)

{
m_value = init_value;
}
bool set_value(const std::string& var_string);
T get_value() const
{
return m_value;
}
private:
T m_value;
};

Потомок = шаблон
Для каждого фиксированного типа реализуется set_value()
Хранение любых наследников возможно по указателю на базовый класс

Слайд 14

Менеджер переменных Поля //! Map of registered variables std::map m_vars; //!

Менеджер переменных

Поля

//! Map of registered variables
std::map m_vars;

//! Map iterator type
typedef std::map::iterator
variable_iterator;
//! Pair type
typedef std::pair variable_pair;
Слайд 15

Регистрация новой переменной Тип неизвестен = шаблонный метод Тип специализации класса-переменной

Регистрация новой переменной

Тип неизвестен = шаблонный метод
Тип специализации класса-переменной = типу

специализации метода регистрации переменной

template
void register_variable(const std::string& var_name, const T& val)
{
variable_pair p( var_name, new variable(val) );
m_vars.insert( p );
}

Слайд 16

Получение значения переменной Для указания значения переменной необходимо указать тип Метод

Получение значения переменной

Для указания значения переменной необходимо указать тип
Метод - шаблонный
Алгоритм
Поиск

по имени переменной
Тип специализации метода = тип специализации наследника variable
Приведение к типу наследника
dynamic_cast
Слайд 17

Получение значения переменной: реализация template bool get_variable(const std::string& var_name, T* var_value)

Получение значения переменной: реализация

template
bool get_variable(const std::string& var_name, T* var_value)
{

variable_iterator var_iter = m_vars.find(var_name);
if (var_iter == m_vars.end())
return false;
variable *var_ptr = dynamic_cast< variable* >(var_iter-> second);
if (var_ptr == NULL)
return false;
*var_value = var_ptr->get_value();
return true;
}
Слайд 18

Закрытый метод set_value Поиск переменной и установка значения bool variable_mgr::set_value(const std::string&

Закрытый метод set_value

Поиск переменной и установка значения

bool variable_mgr::set_value(const std::string& var_name, const

std::string& var_string)
{
variable_iterator var_iter = m_vars.find(var_name);
if (var_iter == m_vars.end())
return false;
return var_iter->second->set_value(var_string);
}
Слайд 19

Парсинг командной строки void variable_mgr::run_parser(int argc, char* argv[]) { int var_id

Парсинг командной строки

void variable_mgr::run_parser(int argc, char* argv[])
{
int var_id = 1;


while ( var_id < argc - 1 )
{
if (!set_value(argv[var_id], argv[var_id + 1]))
{
std::string msg = "ERROR: Either unidentified option or missing parameter: ";
msg += argv[var_id];
throw err::parse_exception(msg);
}
var_id += 2;
}
}
Слайд 20

Указание реализаций set_value Компилятору необходимо указать реализации для всех используемых в

Указание реализаций set_value

Компилятору необходимо указать реализации для всех используемых в коде

специализаций variable

template <>
bool variable::set_value(const std::string& var_string)
{
m_value = static_cast (strtod( var_string.c_str(), NULL));
return true;
}
template <>
bool variable::set_value(const std::string& var_string)
{
m_value = var_string;
return true;
}