Пример 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;
};