Re: Incomplete types and std::vector
* James Kanze:
On Feb 4, 11:07 pm, "Leigh Johnston" <le...@i42.co.uk> wrote:
I've doubtlessly read it, but I'm not convinced. I repeat:
what does std::auto_ptr buy you, compared to a raw pointer?
std::auto_ptr buys you ownership semantics with RAII (no
memory leak if exception is thrown during construction of
class owning the pimpl object). The alternative is to write
your own version of something similar to std::auto_ptr but why
bother? I will use unique_ptr instead when it is available.
Sorry, but that's just false. Whether you use auto_ptr or a raw
pointer changes absolutely nothing during construction.
I think Leigh is referring to something like
Foo::Foo()
: myImpl( std::auto_ptr<Impl>( new Impl ) )
{
// Statement X that might trow
}
If X throws then statements in ~Foo are not executed.
However, the smart pointer ensures that the Impl instance is deleted.
This avoids doing silly things like
Foo::Foo()
{
std::auto_ptr<Impl> pImpl( new Impl );
myImpl = pImpl.get();
// Statement X that might throw
pImpl.release();
}
or even worse with try-catch.
A main catch is that one is using knowledge of how a std::auto_ptr is usually
implemented in order to create code that will work in practice in spite of
formally Undefined Behavior, which is a bit fragile...
And really, what's used is not std::auto_ptr's ownership transfer semantics, but
just its RAII cleanup.
And so even the simplest of the simplest RAII cleanup class would do as a
well-defined substitute, e.g.
template< typename T >
struct AutoDestroyed
{
T* p;
~AutoDestroyed() { destroy( p ); } // Define 'destroy' per type T.
AutoDestroyed( T* const p_ ): p(p_) {}
AutoDestroyed( AutoDestroyed const& );
AutoDestroyed& operator=( AutoDestroyed const& );
};
It is silly saying a <memory> dependency is undesirable.
It's not really a big point, but why add the dependency if it
doesn't buy you anything.
See above.
Cheers,
- Alf