asianmuscle@gmail.com wrote:
Quote:
I am trying to learn RAII and some template techniques by writer a
smarter pointer class to manage the resource management. Since I find
that a lot of the resource management is kinda the same, I try to mimic
some other examples outther then tailor to my needs. My case is for
windows handle like hkey, dll library, file handle, etc. But the code
largely uses standard C++. Only the Clean up action, I put windows api
call in there.
In general, I want to archieve one thing: the template will instantiate
when I give it the inpout type, then call the CloseResource eventually
to clean up on exit of scope.
>
But I have a hard time to make the class to find out what the
NULL_VALUE is. NULL_VALUE is a value that depends on the type. or is
this a worthwhile effort to get rid of that dependency?I defaulted
evertyhing to NULL now but not all type will default to NULL, if I take
extendsibility into account.
See below.
Quote:
Also I notice I end up with a lot of small policy classes. Is there a
way to reduce that number? Because all it depends is the windows API
call. I think I am asking somethign circular here.
Some existing implementations of smart pointers (e.g.,
std::tr1::shared_ptr aka boost::shared_ptr) accept a deleter argument.
That would suffice in a case such as this:
struct SomeHandle { /*...*/ };
SomeHandle* GetResource();
void FreeResource( SomeHandle* );
std::tr1::shared_ptr<SomeHandlehandle(
GetResource(), FreeResource );
You could also use boost::bind or boost::lambda to reduce the number of
simple policies (probably not a good idea if they are used more than
once).
Quote:
For the release policy code:
#include <windows.h>
>
template <typename hType>
struct RegistryPolicy{
void CloseResource(hType& h){
::RegCloseKey(h);
h=NULL; //?
Setting to NULL is probably unnecessary if you're using smart pointers
since the smart pointer is entirely responsible for the resource and
will only call on the release policy when the item is being destroyed
(either on destruction or reset).
Semicolons are not necessary after function definitions. You should
also make this function static since there is no member data in play
here.
Quote:
>
protected: // do I need these or delete those? they are compiler
generated anyway
RegistryPolicy(){};
~RegistryPolicy(){};
They would be generated public by default. You must define them
yourself to override that.
Quote:
private:
RegistryPolicy(RegistryPolicy&);
RegistryPolicy& operator=(RegistryPolicy&);
The function parameter should be const in both cases.
Quote:
};
>
template <typename hType>
struct LibraryPolicy{
void CloseResource(hType& h){
::FreeLibrary(h);
h=NULL; //?
};
protected:
LibraryPolicy(){};
~LibraryPolicy(){};
private:
explicit LibraryPolicy(LibraryPolicy&);
LibraryPolicy& operator=(LibraryPolicy&);
};
>
>
template <typename hType>
struct CloseViewOfFile{
void CloseResource(hType& h){
::UnmapViewOfFile(h);
h=NULL; //?
};
protected:
explicit CloseViewOfFile(){};
~CloseViewOfFile(){};
private:
CloseViewOfFile(CloseViewOfFile&);
CloseViewOfFile& operator=(CloseViewOfFile&);
>
};
///////////////////////////// my smarter pointer code in below
//////////////////////////////
template <class T>
void DestroyObject(T object) {object->Destroy();}
>
template <class T>
void DesposeObject(T object) {object->CloseResource();}
Dispose?
Quote:
>
//
//
>
template <typename hType,
template<typenameclass ReleasePolicy=DeposeObject,
DisposeObject?
Quote:
hType NULL_VALUE=NULL>//how to generalize NULL_VALUE? makeit
get the value depending on the type?
Use the default value of hType:
template
<
typename hType,
template<typenameclass ReleasePolicy=DisposeObject,
hType NULL_VALUE=hType()
class SmartHolder;
Quote:
class SmarterHolder{
private:
hType mhandle;
>
void CleanUp(){
if (NULL_VALUE!= mhandle)
{
ReleasePolicy(mhandle);
mhandle = NULL_VALUE;
}
}
hType operator=(hType);
SmarterHolder(SmarterHolder&);
>
public:
explicit SmarterHolder():mhandle(NULL_VALUE){};
explicit SmarterHolder(hType h): mhandle(h){};
~SmarterHolder(){ ReleasePolicy(); };
operator hType () const { return mhandle; }
bool IsValidHandle() const { return NULL_VALUE != mhandle; }
};
#endif
I'd suggest that, rather than rolling your own, you should switch to
using a tried-and-true RAII mechanism like std::tr1::/boost::shared_ptr
(where you would supply a custom deleter) or even Loki::SmartPtr (where
you would supply a storage policy). No need to reinvent the wheel.
Cheers! --M