﻿# V2539\. MISRA\. Class destructor should not exit with an exception\.

Данное диагностическое правило основано на руководстве [MISRA](https://www.misra.org.uk/) \(Motor Industry Software Reliability Association\) по разработке программного обеспечения\.

Это правило справедливо только для C\+\+\. Бросание исключения в деструкторе объекта \- плохая практика\. Начиная с C\+\+11, бросание исключения в теле деструктора приводит к вызову функции 'std::terminate'\. Из этого следует, что исключение, брошенное внутри деструктора, должно быть обработано внутри того же деструктора\.

Рассмотрим первый пример:

```cpp
LocalStorage::~LocalStorage()
{
  ...
  if (!FooFree(m_index))
    throw Err("FooFree", GetLastError());
  ...
}
```

Анализатор обнаружил деструктор, содержащий оператор throw вне блока try\.\.catch\. Данный код следует переписать таким образом, чтобы сообщить об ошибке, возникшей в деструкторе без использования механизма исключений\. Если ошибка не критична, то ее можно игнорировать:

```cpp
LocalStorage::~LocalStorage()
{
  try {
    ...
    if (!FooFree(m_index))
      throw Err("FooFree", GetLastError());
    ...
  }
  catch (...)
  {
    assert(false);
  }
}
```

Также исключения могут возникать при вызове оператора 'new'\. При невозможности выделения памяти будет сгенерировано исключение 'std::bad\_alloc'\. Рассмотрим второй пример:

```cpp
A::~A()
{
  ...
  int *localPointer = new int[MAX_SIZE];
  ...
}
```

Появление исключения также возможно и при использовании dynamic\_cast<Type\> при работе с ссылками\. При невозможности приведения типов будет сгенерировано исключение 'std::bad\_cast'\. Рассмотрим третий пример:

```cpp
B::~B()
{
  ...
  UserType &type = dynamic_cast<UserType&>(baseType);
  ...
}
```

Для исправления данных ошибок следует переписать код таким образом, чтобы 'new' или 'dynamic\_cast' были помещены в блок 'try\-catch'\.