Re: when to call auto_ptr release?
George wrote:
In the past, I would use aggregate model or contain model to define a
resource class, customize the resource release function and put it into
destructor, then use auto_ptr to wrap.
Well, that would mean that for a simple HANDLE, you would create a class
that holds it and invokes CloseHandle() in the destructor. Then, in order
to pass this resource around, you would create an instance of the wrapper
via new and pass an auto_ptr to it around.
Some problems there:
1. You invoke new in order to allocate four or eight bytes of storage.
Allocations of free storage are expensive, so I would rather avoid them if
there is a clean way. Also, this can theoretically fail.
2. Unless you also provide a release() function, your code is not as
flexible. Sure, it is to some extent safer, because there is nothing that
could go wrong.
3. It requires additional code, because both the auto_ptr could be null and
the contained HANDLE itself can be null. You could change this by stating
that a non-null HANDLE is a class invariant and then throw in the
constructor. It depends on the context whether that makes sense.
For this part of code,
struct ref
{
handle_type h;
};
operator ref()
{
ref r = {m_handle};
release();
return r;
}
I do not know (1) what is your designed function of ref operator and (2)
why do you define an internal struct ref. Any comments?
(I searched your code for ref usage but can not find a sample)
The code uses it, but the user doesn't use it explicitly and never should
(which I should have documented) because it is prone to resource leakage
except in the few cases it was designed for.
Anyway, take a look at open_fd(). There, an auto_handle is returned. In
main(), this is used to initialise another instance of this class. However,
note that the constructor taking an auto_handle takes it as non-const(!)
reference though. This means that you can't invoke it on a temporary
because those can't be bound to non-const references. What happens instead
is that the temporary is converted to a nested ref type and the constructor
taking that ref type is invoked.
Note: not all VC compilers actually enforce this, so you might be able to
remove this without causing errors.
For this part of code in your comments,
template<>
resource_traits<filedescriptor>
[...]
Is it a typo (missing struct), and should be written as
template<>
struct resource_traits<filedescriptor>
[...]
Yes, that's a typo.
I have tested in Visual Studio 2008, it can not compile. I do not know if
other compiler allows this.
What exactly are the errors? I just ran that thing through GCC 4 and it
works there.
Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite
Sator Laser GmbH
Gesch??ftsf??hrer: Michael W??hrmann, Amtsgericht Hamburg HR B62 932