Создание HANDLE RAII-совместимого с использованием shared_ptr с пользовательским средством удаления

Это может помочь:

1) меню «Build» -> «Rebuild Project». Иногда Intellij не переписывает классы, потому что они уже существуют, таким образом вы просите Intellij переписать все.

2) Меню «Выполнить» -> «Edit configuration» -> удалить профиль -> добавить назад профиль («Приложение», если это приложение Java), выберите свой основной класс из раскрывающегося меню «Основной класс».

3) Меню «Сборка» -> «Rebuild Project».

11
задан Community 23 May 2017 в 11:54
поделиться

2 ответа

Пример 1 в порядке

Пример 2 неверен. При слепом преобразовании в PHANDLE логика shared_ptr игнорируется. Вместо этого должно получиться что-то вроде этого:

HANDLE h;
OpenProcessToken(...., &h);
shared_ptr<void> safe_h(h, &::CloseHandle);

или, чтобы назначить ранее существовавшему shared_ptr:

shared_ptr<void> safe_h = ....
{
  HANDLE h;
  OpenProcessToken(...., &h);
  safe_h.reset(h, &::CloseHandle);
}//For extra safety, limit visibility of the naked handle

, или создать свою собственную безопасную версию OpenProcessToken, которая возвращает общий дескриптор вместо использования PHANDLE:

// Using SharedHandle defined at the end of this post
SharedHandle OpenProcess(....)
{
    HANDLE h = INVALID_HANDLE_VALUE;
    ::OpenProcessToken(...., &h);
    return SharedHandle(h);
}

Пример 3: Нет необходимости идти в объездные пути. Это должно быть нормально:

Process32First(h.get(), ...);

Пример 4: Опять же, без обходного пути:

if (h.get() == INVALID_HANDLE){...}

Чтобы было удобнее, вы можете ввести что-то вроде:

typedef shared_ptr<void> SharedHandle;

или еще лучше, если все дескрипторы должны быть закрыты с помощью CloseHandle (), создайте класс SharedHandle, заключающий в оболочку shared_ptr и автоматически предоставляющий правильное средство удаления:

// Warning: Not tested. For illustration purposes only
class SharedHandle
{
public:
  explicit SharedHandle(HANDLE h) : m_Handle(h, &::CloseHandle){};
  HANDLE get()const{return m_Handle.get();}

  //Expose other shared_ptr-like methods as needed
  //...

private:
  shared_ptr<void> m_Handle;
};
9
ответ дан 3 December 2019 в 08:04
поделиться
2
ответ дан 3 December 2019 в 08:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: