Downcasting using the 'static_cast' in C++
Consider:
class base
{
base();
virtual void func();
}
class derived : public base
{
derived();
void func();
void func_d();
int a;
}
main
{
base *b = new base();
sizeof(*b); // Gives 4.
de开发者_开发知识库rived * d = static_cast<derived*>(b);
sizeof(*d); // Gives 8- means whole derived obj size..why?
d->func_d();
}
In the above code I did downcasting of a base pointer which points to base object to derived class pointer. I am wondering how the derived pointer has the whole derived class object. I can call the derived class function (declared in derived class only). I did not get the concept here.
Using static_cast
to cast an object to a type it doesn't actually have yields undefined behavior. The symptoms of UB vary widely. There's nothing that says UB can't allow the derived member function to be called successfully (but there's nothing that guarantees that it will, so don't count on it).
Here is the rule for downcasting using static_cast
, found in section 5.2.9 ([expr.static.cast]
) of the C++ standard (C++0x wording):
A prvalue of type "pointer to cv1
B
", whereB
is a class type, can be converted to a prvalue of type "pointer to cv2D
", whereD
is a class derived fromB
, if a valid standard conversion from "pointer toD
" to "pointer toB
" exists, cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, andB
is neither a virtual base class ofD
nor a base class of a virtual base class ofD
. The null pointer value is converted to the null pointer value of the destination type. If the prvalue of type "pointer to cv1B
" points to aB
that is actually a subobject of an object of typeD
, the resulting pointer points to the enclosing object of typeD
. Otherwise, the result of the cast is undefined.
The only cast that does runtime checking is dynamic_cast<>()
. If there is any possibility that a cast will not work at runtime then this cast should be used.
Thus casting from leaf->root (up casting) static_cast<>()
works fine.
But casting from root->leaf (down casting) is dangerous and (in my opinion) should always be done with dynamic_cast<>()
as there will be dependencies on run-time information. The cost is slight, but always worth paying for safety.
sizeof
exists at compile-time. It neither knows nor cares that at run-time, your base object doesn't point to a derived
. You are attempting to influence compile-time behaviour with a run-time variable, which is fundamentally impossible.
精彩评论