Re: dynamic_cast is only casting right?
Victor Bazarov wrote:
On 6/2/2010 10:24 AM, A wrote:
in a function:
void Image_AssignImage(TObject *Sender)
{
dynamic_cast<TObjectDescendant *>(Sender)->DoWhatever();
}
in above function dynamic_cast is simply casting Tobject into compatible
TObjectDescendant and then calls function DoWhatever contained in
TObjectDescendant (and not in Tobject)?
The above does not need any kind of delete or something like that
right? I
suppose it does not but would like to verify this.
(note: Sender always points to existing object that is deleted on program
exit so does not need deleting itself in above example)
The cast can fail. A failed pointer cast yields a null pointer and as
such will make the behaviour of your program undefined. A failed
reference cast throws 'std::bad_cast' exception. It's better to do
void Image_Asssign...
{
if (TObjectDescendant* pD = dynamic_cast<...>(Sender))
pD->DoWhatever();
else
// report the error somehow
}
Also, consider looking at boost::polymorphic_cast for even better casting:
http://www.boost.org/doc/libs/1_43_0/libs/conversion/cast.htm#Polymorphic_cast
It isn't really any better than the code above, but getting into the
habit of using it instead of dynamic_cast, you have a more predictable
error when you forget to do the error check. In other words, if you do
this:
dynamic_cast<...>(Sender)->DoWhatever();
and forget to do what was above (with the check for a failed cast by
checking for NULL) and the cast fails, the behavior is undefined,
whereas if you use boost::polymorphic_cast:
try {
boost::polymorphic_cast<...>(Sender)->DoWhatever();
} catch (const std::bad_cast &) {
// deal with the fact that it didn't cast
}
and instead forget to do the try/catch:
boost::polymorphic_cast<...>(Sender)->DoWhatever();
at least now you will have predictable behavior of an uncaught exception.
Both dynamic_cast and boost::polymorphic_cast need supporting cast
checking, but by getting into the habit of using boost::polymorphic_cast
(if boost is available to you), if/when you forget to do the cast check,
the bug will produce predictable results.
Adding the try/catch might have a performance impact, but to choose
dynamic_cast instead for that reason without just-cause would probably
be a premature optimization.
Also, if you know that it will be a cast that always succeeds and need
higher performance, consider using boost::polymorphic_downcast which
will use a dynamic_cast and assert in debug builds, but use a
static_cast in release builds for performance.
Mark