auto_ptr and casting

J

James Juno

Hello,

I want to do something like this:

class A
{
...
};

class B : public A
{
...
};

void someFunction(const std::auto_ptr<A>& ptr)
{
B* b = dynamic_cast<B*>(ptr.get());
...
}

Is what I've done here the correct/safe way to handle this using auto_ptr?

Thanks!
JJ
 
A

Alf P. Steinbach

* James Juno:
I want to do something like this:

class A
{
...
};

class B : public A
{
...
};

void someFunction(const std::auto_ptr<A>& ptr)
{
B* b = dynamic_cast<B*>(ptr.get());
...
}

Is what I've done here the correct/safe way to handle this using auto_ptr?

No, you cannot pass std::auto_ptr by reference to const.

For dynamic_cast class A must be polymorphic.

It's not clear what you're trying to do.
 
M

mlimber

James said:
Hello,

I want to do something like this:

class A
{
...
};

class B : public A
{
...
};

void someFunction(const std::auto_ptr<A>& ptr)
{
B* b = dynamic_cast<B*>(ptr.get());
...
}

Is what I've done here the correct/safe way to handle this using auto_ptr?

Thanks!
JJ

No. First of all dynamic_cast can indicate poor design. Re-examine
yours. Second, the function should look like this:

void someFunction( std::auto_ptr<A>& a )
{
std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
...
}

You'll also want to check if b.get() is null, in which case the cast
failed.

Cheers! --M
 
J

James Juno

Alf said:
* James Juno:

No, you cannot pass std::auto_ptr by reference to const.

For dynamic_cast class A must be polymorphic.

It's not clear what you're trying to do.

I got the idea to pass as const reference from "The C++ Standard
Library" by N. Josuttis. By the way, this compiles and seems to work
fine in vc.net, I just didn't know if it was "safe." The auto_ptr
variable's type is set at runtime in the caller (one of several possible
decendants of A) so I never know what I'm getting in the call to
someFunction(). I am just using dynamic_cast as a debug check. Sorry
for being unclear, a better explanation of this function might be:

void someFunction(int type, const std::auto_ptr<A&> ptr)
{
// <type> is an enum defined elsewhere
switch (type)
{
case B:
#ifdef _DEBUG
B* b = dynamic_cast<B*>(ptr.get());
assert(b);
#else
B* b = static_cast<B*>(ptr.get());
#endif

...
case C:
... etc
}
}
 
A

Andre Kostur

(e-mail address removed) (Alf P. Steinbach) wrote in

* James Juno:

No, you cannot pass std::auto_ptr by reference to const.

Huh? Why not? As long as no modifying operations are called on ptr....
 
A

Andre Kostur

No. First of all dynamic_cast can indicate poor design. Re-examine
yours. Second, the function should look like this:

void someFunction( std::auto_ptr<A>& a )
{
std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
...
}

Only if the OP is attempting to transfer ownership of the pointer into
someFunction. Perhaps the OP is only attempting to use the B object.
 
J

James Juno

mlimber said:
No. First of all dynamic_cast can indicate poor design. Re-examine
yours. Second, the function should look like this:

void someFunction( std::auto_ptr<A>& a )
{
std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
...
}

You'll also want to check if b.get() is null, in which case the cast
failed.

Cheers! --M

Perfect, thanks! That's exactly what I was looking for. The
dynamic_cast I'm using if just for debugging, sort of like:

void someFunction(int type, const std::auto_ptr<A>& ptr)
{
// <type> is an enum defined elsewhere
switch (type)
{
case B:

#ifdef _DEBUG
B* b = dynamic_cast<B*>(ptr.get());
assert(b != 0);
#else
B* b = static_cast<B*>(ptr.get());
#endif

...
case C:
... etc
}
}
 
A

Alf P. Steinbach

* James Juno:
I got the idea to pass as const reference from "The C++ Standard
Library" by N. Josuttis.

Well, correction: you cannot pass a temporary (such as a function result) as
argument here (technical reason, not allowed by the standard), and you
shouldn't pass a variable here (style issue, passing auto_ptr implies
passing ownership, which doesn't occur when passing by reference).

By the way, this compiles and seems to work fine in vc.net,

MSVC is mostly incorrect wrt. std::auto_ptr.

Regarding casting, consider using base class virtual functions, which you
need anyway for dynamic_cast.
 
M

mlimber

James said:
Perfect, thanks! That's exactly what I was looking for. The
dynamic_cast I'm using if just for debugging, sort of like:

void someFunction(int type, const std::auto_ptr<A>& ptr)
{
// <type> is an enum defined elsewhere
switch (type)
{
case B:

#ifdef _DEBUG
B* b = dynamic_cast<B*>(ptr.get());
assert(b != 0);
#else
B* b = static_cast<B*>(ptr.get());
#endif

...
case C:
... etc
}
}

On second thought, the code I supplied would leak memory if the cast
failed. Try this:

void someFunction( std::auto_ptr<A>& a )
{
A* const rawA = a.release();
std::auto_ptr<B> b( dynamic_cast<B*>(rawA) );
if( b.get() )
{
...
}
else
{
delete rawA;
}
}

Cheers! --M
 
A

Alf P. Steinbach

* Andre Kostur:
(e-mail address removed) (Alf P. Steinbach) wrote in



Huh? Why not? As long as no modifying operations are called on ptr....

You cannot pass a temporary as actual argument because std::auto_ptr does
not have a copy constructor taking std::auto_ptr by reference to const.

You can but shouldn't pass a variable as actual argument.
 
J

James Juno

Andre said:
Only if the OP is attempting to transfer ownership of the pointer into
someFunction. Perhaps the OP is only attempting to use the B object.

Yes, the OP is only trying to use the object. If style semantics dictate
that an auto_ptr as a function parameter should imply ownership
transfer, then what's better in this case? It's becoming more of a
headache to use auto_ptr than to just deal with resource management
manually.
 
M

mlimber

James said:
Yes, the OP is only trying to use the object. If style semantics dictate
that an auto_ptr as a function parameter should imply ownership
transfer, then what's better in this case? It's becoming more of a
headache to use auto_ptr than to just deal with resource management
manually.

If you don't intend to transfer ownership to the function, then your
original code looks fine.

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top