Что такое RAII

«Что такое RAII» — вопрос из категории Управление памятью, который задают на 43% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

RAII (Resource Acquisition Is Initialization) — это фундаментальная идиома C++, которая связывает время жизни ресурса (памяти, файлового дескриптора, сетевого сокета, мьютекса) со временем жизни объекта. Ресурс захватывается в конструкторе объекта и гарантированно освобождается в его деструкторе.

Почему это важно: Это обеспечивает безопасность при исключениях и исключает утечки ресурсов, так как деструктор вызывается автоматически при выходе объекта из области видимости (даже если это произошло из-за выброса исключения).

Практические примеры из C++:

  1. Умные указатели (std::unique_ptr, std::shared_ptr) — классический пример RAII для динамической памяти.

    {
        std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>(); // Память выделена
        ptr->doWork();
        // Если здесь выбросится исключение...
    } // ... память всё равно будет освобождена здесь в деструкторе `ptr`.
  2. Работа с файлами (std::fstream).

  3. Блокировки мьютексов (std::lock_guard).

    void safe_increment() {
        std::lock_guard<std::mutex> lock(my_mutex); // Мьютекс захвачен
        shared_variable++; // Критическая секция
    } // Мьютекс гарантированно освобождён здесь, даже если increment выбросит исключение
  4. Собственный RAII-класс для работы с WinAPI/C API (например, дескриптор файла):

    class FileHandle {
        HANDLE hFile;
    public:
        explicit FileHandle(const wchar_t* path) : hFile(CreateFile(path, ...)) {
            if (hFile == INVALID_HANDLE_VALUE) throw std::runtime_error("Cannot open file");
        }
        ~FileHandle() { if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); }
        // Запрещаем копирование, разрешаем перемещение (Rule of Five)
        FileHandle(const FileHandle&) = delete;
        FileHandle& operator=(const FileHandle&) = delete;
        FileHandle(FileHandle&& other) noexcept : hFile(other.hFile) { other.hFile = INVALID_HANDLE_VALUE; }
        // ... методы для работы с дескриптором
    };

    RAII — это основа написания безопасного и чистого C++ кода.