edA-qa mort-ora-y
edA-qa mort-ora-y

Reputation: 31871

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'm 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

Upvotes: 4

Views: 2231

Answers (3)

Luc Danton
Luc Danton

Reputation: 35449

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;
}

Upvotes: 4

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145279

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.,

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 473447

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..

Upvotes: 1

Related Questions