Click here to Skip to main content
15,861,125 members
Articles / Programming Languages / C++

Scoped Handle - "Smart pointer" for Windows objects

Rate me:
Please Sign up or sign in to vote.
4.33/5 (6 votes)
21 Jul 2010CPOL2 min read 43.4K   226   8   15
Introduces a scoped handle template class to call delete handle methods automatically.

Introduction

One of the common problems with Windows object handles to solve is to prevent resource leaks. In other words, it is necessary not to forget to call the appropriate delete handle method.

To call the appropriate delete handle method explicitly "by hand" is annoying and error prone. Moreover, to call the appropriate delete handle method during an exception is impossible. Therefore, some automatic calling of the delete handle method would be very handy.

This article describes the simple universal solution of this problem using the well-known RAII (Resource Acquisition Is Initialization) technique. It introduces a scoped handle class which calls in its destructor the appropriate delete handle method.

This scoped handle class has a very similar implementation to the smart pointer scoped_ptr from the boost C++ library.

Solution

The easy solution is to introduce the scoped handle class which calls in its destructor the delete handle method.

However, the Windows API world is not so straightforward. There is no common delete methods for all handles. For example, handle returned from the CreateEvent() API method needs to be deleted by the CloseHandle() method. But handle returned from the FindFirstFile() API method needs to be deleted by the FindClose() method.

Moreover, even the invalid handle definition is not always the same. For example, handle returned from the CreateEvent() API method is invalid when it is NULL. But handle returned from the CreateFile() API method is invalid when it is INVALID_HANDLE_VALUE.

To avoid many similar scoped handle implementations, universal template solution is introduced:

C++
template <typename HandleType, class InvalidValue, class CloseMethod>
class ScopedHandle
{
};

This template has three parameters:

  • HandleType - The type of the Windows API handle. E.g., HANDLE, SOCKET, HMODULE.
  • InvalidValue - The class which implements a static public method Get() which returns the invalid handle value.
  • CloseMethod - The class which implements a static public method Close() which deletes the given handle.

The reason why the template does not use non-class parameters is to support old C++ compilers as well.

Usage

The following is the definition of the scoped handle class for handle returned from the CreateFile() method:

C++
class InvalidHandleValue
{
  public:
        static inline HANDLE Get() { return INVALID_HANDLE_VALUE; }
};

class CloseHandleMethod
{
  public:
        static inline void Close(HANDLE Handle) { CloseHandle(Handle); }
};

typedef ScopedHandle<HANDLE, InvalidHandleValue, CloseHandleMethod> FileScopedHandle;

The usage is as follows:

C++
FileScopedHandle File( CreateFile(_T("SomeFile.bin"), GENERIC_READ, 0, 
                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) );
if (!File)
  throw std::runtime_error("File open failure!");
const DWORD FileSize = GetFileSize(File.Get(), NULL);

Conclusion

This article shows the implementation and usage of a scoped handle class which automatically calls the delete handle method during its destruction.

This class is easy to use, and it is flexible enough for almost all possible object handles. To use this class means to avoid any possible resource leaks, and you will not have to pay any attention to this problem anymore.

Links

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Eccam s.r.o.
Czech Republic Czech Republic
Senior Sofware Developer focused on embedded systems.
Company website: http://www.eccam.com

Comments and Discussions

 
GeneralMy vote of 4 Pin
Joxemi28-Jul-10 2:13
Joxemi28-Jul-10 2:13 
GeneralMy vote of 5 Pin
S.H.Bouwhuis26-Jul-10 22:55
S.H.Bouwhuis26-Jul-10 22:55 
I for one like this article because it not only raises awareness for starting developers, but it also adds the 'invalid value' test which is actually really handy.

I won't use this myself, but am thankful for the info.
GeneralAnother article with a similar topic Pin
Nemanja Trifunovic22-Jul-10 23:18
Nemanja Trifunovic22-Jul-10 23:18 
GeneralMy vote of 4 Pin
Aescleal22-Jul-10 22:44
Aescleal22-Jul-10 22:44 
GeneralMy vote of 2 Pin
Aescleal22-Jul-10 2:41
Aescleal22-Jul-10 2:41 
GeneralRe: My vote of 2 Pin
Andre xxxxxxx22-Jul-10 4:57
Andre xxxxxxx22-Jul-10 4:57 
GeneralRe: My vote of 2 Pin
Aescleal22-Jul-10 5:33
Aescleal22-Jul-10 5:33 
GeneralRe: My vote of 2 Pin
Emilio Garavaglia22-Jul-10 11:46
Emilio Garavaglia22-Jul-10 11:46 
GeneralRe: My vote of 2 [modified] Pin
Aescleal22-Jul-10 20:11
Aescleal22-Jul-10 20:11 
GeneralRe: My vote of 2 Pin
Miki Rozloznik22-Jul-10 21:47
Miki Rozloznik22-Jul-10 21:47 
GeneralRe: My vote of 2 Pin
Emilio Garavaglia22-Jul-10 21:48
Emilio Garavaglia22-Jul-10 21:48 
GeneralRe: My vote of 2 Pin
Miki Rozloznik22-Jul-10 20:25
Miki Rozloznik22-Jul-10 20:25 
GeneralRe: My vote of 2 Pin
Aescleal22-Jul-10 22:40
Aescleal22-Jul-10 22:40 
GeneralGood idea, just some small thing: Pin
imagiro21-Jul-10 21:43
imagiro21-Jul-10 21:43 
GeneralRe: Good idea, just some small thing: Pin
Miki Rozloznik22-Jul-10 2:32
Miki Rozloznik22-Jul-10 2:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.