Click here to Skip to main content
15,881,882 members
Articles / Multimedia / GDI

boost 2: shared_ptr wraps resource handles

Rate me:
Please Sign up or sign in to vote.
4.96/5 (41 votes)
16 Nov 200415 min read 228.1K   1.3K   56  
Using boost, we can write "almost perfect" wrappers for GDI and other resource handles, in a few lines of code.
#include "stdafx.h"
#include <crtdbg.h>
#include <boost/shared_ptr.hpp>

// this is sample source code for my CodeProject article.
// it serves no purpose except demosntrating an idea.. 
// For some "reusable" code, see boostsp_reshandle.h
//
// Copyright (C) 2004 Peter Hauptmann all rights reserved
// code provided "AS IS".
// 
// The related header with production code is "handleref.h"
// 
//



// -------------------------------------------------
// Step 1: the HFONT sample:
//

namespace nsFontHandle_1
{


// (a) typedef for the smart pointer to a font
typedef boost::shared_ptr<HFONT> CFontPtr;

// (b) custom deleter for the font
void delete_HFONT(HFONT * p)
{
    DeleteObject(*p);
    delete p;
}


// (c) a helper function to initialize the handle
CFontPtr CreateFontPtr(HFONT font, bool deleteOnRelease)
{
  if (deleteOnRelease) {
    // construct a new FontPtr. the custom deleter is specified as second argument
   return CFontPtr(new HFONT(font), delete_HFONT);  
  }
  else {
    // construct a new FontPtr with the default deleter:
    return CFontPtr(new HFONT(font));
  }
}


} // namespace nsFontHandle_1




// -------------------------------------------------
// Step 2: the CFontRef class
//

namespace nsFontHandle_2
{

// (a) the same deleter as in Sample 1
void delete_HFONT(HFONT * p)
{
    DeleteObject(*p);
    delete p;
}


// (b) a custom class 
class CFontRef
{
protected:
    typedef boost::shared_ptr<HFONT>    tBoostSP;
    tBoostSP    m_ptr;

public:
    explicit CFontRef(HFONT font, bool deleteOnRelease)
    {
        if (deleteOnRelease)
            m_ptr = tBoostSP(new HFONT(font), delete_HFONT);
        else
            m_ptr = tBoostSP(new HFONT(font));
    }

    operator HFONT() const { return m_ptr ? *m_ptr : NULL; }
};

} // namespace nsFontHandle_2



// -------------------------------------------------
// Step 3: using a template
//

namespace nsFontHandle_3
{

// (a) templatizing the CFontRef class over handle and Deleter
template <typename HDL, typename DELETER>
class CHandleRef
{
protected:
    typedef boost::shared_ptr<HDL>    tBoostSP;
    tBoostSP    m_ptr;

public:
    explicit CHandleRef(HFONT font, bool deleteOnRelease)
    {
        if (deleteOnRelease)
            m_ptr = tBoostSP(new HFONT(font), DELETER());
        else
            m_ptr = tBoostSP(new HFONT(font));
    }

    operator HDL() const { return m_ptr ? *m_ptr : NULL; }
};

// (b) the HFONT Deleter - turned into a functor
struct CDeleterT_HFONT
{
    void operator()(HFONT * p) { DeleteObject(*p); delete p; }
};


// (c) a generic HFONT deleter for GDI Objects
template <typename GDIHANDLE>
struct CDeleterT_GDIObject
{
    void operator()(GDIHANDLE * p) {DeleteObject(*p); delete p; }
};


typedef CHandleRef<HFONT, CDeleterT_GDIObject<HFONT> > CFontRef;

} // namespace nsFontHandle_3



// -------------------------------------------------
// Step 4: relying on void *
// this is the "final" code you also find in the handleref.h header
//

namespace nsFontHandle_4
{

// (a) the template class with the same interface, but simmplified implementation
template <typename HDL, typename DELETER>
class CHandleRef
{
protected:
    typedef boost::shared_ptr<void> tBoostSP;
    tBoostSP m_ptr;

public:
    explicit CHandleRef(HFONT font, bool deleteOnRelease)
    {
        if (deleteOnRelease)
            m_ptr = tBoostSP(font, DELETER());
        else
            m_ptr = tBoostSP(font);
    }

    operator HDL() const { return (HDL) m_ptr.get(); }
};

// (b) GDI Object Deleting functor, also not a template anymore
struct CDeleter_GDIObject
{
    void operator()(void * p) { DeleteObject(p); }
};

typedef CHandleRef<HFONT, CDeleter_GDIObject> CFontRef;

}



int main()
{
    return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Klippel
Germany Germany
Peter is tired of being called "Mr. Chen", even so certain individuals insist on it. No, he's not chinese.

Peter has seen lots of boxes you youngsters wouldn't even accept as calculators. He is proud of having visited the insides of a 16 Bit Machine.

In his spare time he ponders new ways of turning groceries into biohazards, or tries to coax South American officials to add some stamps to his passport.

Beyond these trivialities Peter works for Klippel[^], a small german company that wants to make mankind happier by selling them novel loudspeaker measurement equipment.


Where are you from?[^]



Please, if you are using one of my articles for anything, just leave me a comment. Seeing that this stuff is actually useful to someone is what keeps me posting and updating them.
Should you happen to not like it, tell me, too

Comments and Discussions