auto_ptr and dynamic_pointer_cast
If I wish to use dynamic_cast
with a shared_ptr
I can use dynamic_pointer_cast
. What do I use if I wish to cast an auto_ptr
? I'开发者_如何学Pythonm assuming something that would look like below.
struct B : A { };
...
auto_ptr<A> base( ... );
auto_ptr<B> derive = dynamic_pointer_cast<B>(base);
I'm using boost for shared_ptr's
auto_ptr<A> base( ... );
if(B* query = dynamic_cast<B>(base.get())) {
// take ownership
base.release();
auto_ptr<B> derived(query);
// use and/or pass derived around here
// ...
} else {
// no dice: leave base as owner
}
Since you're already doing that, then refactor it, slap it in the namespace of your choice and call it a day:
// Postcondition:
// where r is the returned pointer and p == from.get()
// EITHER r == 0 AND from.get() == p
// OR r.get() == dynamic_cast<To>(p) AND from == 0
template<typename To, typename From>
std::auto_ptr<To>
dynamic_pointer_cast(std::auto_ptr<From>& from)
{
To* query = dynamic_cast<To>(from.get());
return query ? from.release(), query : 0;
}
By the nature of auto_ptr
(which you should never use. Or if you have to use it, never copy-construct or copy-assign it), copying is equivalent to moving. Therefore, there is no way to do a cast without transferring ownership, which causes the previous owner to lose ownership.
And what would happen if it returned an empty auto_ptr
(meaning a failed dynamic_cast
)? The original owner of the pointer has lost ownership, thanks to the cast. The new owner doesn't have the pointer, since the cast failed. So who would own it?
I'm sure you can partially specialize dynamic_pointer_cast for any pointer type you want however.
Also, auto_ptr
is deprecated in C++0x; the standards committee isn't going to promote the use of deprecated functionality by making dynamic_pointer_cast
work with it..
It would go like this:
auto_ptr<Derived> pd(
dynamic_cast<Derived*>( base.get() )? static_cast<Derived*>( base.release() ) : 0
);
Then check whether an ownership transfer did occur.
If it didn't, you might reset
the original auto_ptr
, and throw an exception.
Since especially Microsoft's implementation of auto_ptr
has been very shaky, and probably still is, it's important to not rely on the conversions guaranteed by the standard.
Cheers & hth.,
精彩评论