RAII и исключения в конструкторе
От: C0x  
Дата: 04.07.20 10:23
Оценка:
Привет,

давно не писал на плюсах, вот вернулся снова и понеслась душа в пляс

Надоели всякие Begin, End, Open, Close методы в программах. Хочу придерживаться принципа RAII.
Но возникает классическая проблема вылетает исключение в конструкторе и пипец. Ну скажем я Handle какой-нибудь на ресурс получил, а после исключения естественно деструктор не вызывается и ресурс не освобождается. Ну как бы, да, есть ломовое решение перехватывать закрыть конструктор в try catch и освобождать ресурсы через метод Release(), которой так же дергается и в самом деструкторе нашего класса.
Но как вам решение проблемы деструкции данных класса через базовый класс? Т.е. пихаем все ресурсные поля класса в базовый класс, который умеет их зачищать в деструкторе. После того как в нашем классе в конструкторе вылетает исключение, в любом случае вызовится деструктор базового класса и он освободит ресурсы. Есть такой подход в Си++ мире или лучше так не делать?

Со своей стороны я вижу очевидный плюс такого подхода — нет лишних методов типа Release, Close и т.д. Все делается средствами самого языка: конструктор-деструктор. Как бы чисто всё чтоли.

Пример:

template<typename TData>
struct A : public TData
{
  
  A()
  {
    _someHandle1 = LoadHeavyResource1(); //Тут может быть исключение
    _someHandle2 = LoadHeavyResource2(); //Тут может быть исключение
    _someHandle3 = LoadHeavyResource3(); //Тут может быть исключение
  }

}

struct A_Data
{
   HANDLE _someHandle1 = NULL;
   HANDLE _someHandle2 = NULL;
   HANDLE _someHandle3 = NULL;

   ~A_Data()
   {
     if (_someHandle1 != NULL) ReleaseHeavyResource1(_someHandle1);
     if (_someHandle2 != NULL) ReleaseHeavyResource2(_someHandle2);
     if (_someHandle3 != NULL) ReleaseHeavyResource3(_someHandle3);
   }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.