I need to know under which conditions static_cast
can be used in order to convert a parent class pointer to a child class pointer without causing an undefined behavior.
Usually dynamic_cast
is recommended for safe downcasting, but what if the pointer that originally pointed to a parent class object never uses any member of the child class? Is it safe to use static_cast
in this case?
If yes, then the following example code should not lead to any undefined behavior.
Example:
struct Parent {
int i = 3;
void print() { std::cout << i << std::endl; }
};
struct Child : Parent {
double d = 5;
void change() { i *= 2; }
};
int main() {
Parent* pParent = new Parent;
Child* pChild = static_cast<Child*>(pParent);
pChild->print(); //should be ok
//std::cout << pChild->d << std::endl; //undefined behavior
//pChild->change(); //does this lead to an undefined behavior?
}
Bonus question: Is it safe to use a member function from the child class, if that function only uses members from the parent class? In the example above this would mean the use of
pChild->change();
Goal:
My goal is to avoid dynamic_cast
in order to safe performance. As long as I know how to avoid an undefined behavior for sure I am willing to take the risk of using static_cast
instead.
There are already existing threads about downcasting with static_cast
, but none of them really answers under which conditions an undefined behavior can be avoided.
but what if the pointer that originally pointed to a parent class object never uses any member of the child class? Is it safe to use static_cast in this case?
No, the behavior is still undefined.
If yes, then the following example code should not lead to any undefined behavior.
The example has undefined behavior because pParent
points to an object of type Parent
that is not a base class subobject of some Child
object, which according to the standard causes causes static_cast<Child*>(pParent)
to have undefined behavior.
Bonus question: Is it safe to use a member function from the child class, if that function only uses members from the parent class?
No, the cast itself, even if the result is not used at all, has undefined behavior.
Goal: My goal is to avoid dynamic_cast in order to safe performance.
You can use static_cast
safely for downcasts in exactly the same circumstances in which dynamic_cast
would not return a null pointer. In the other cases, the static_cast
will have undefined behavior. That's precisely why static_cast
is faster.
It is impossible to obtain a pointer to a Child
if the Parent
object wasn't created as base class subobject while creating a Child
object. The language does not permit this at all. To operate on a Child*
in any way, you need to create a Child
object first.
Usually it is better to use an appropriate virtual
function interface instead of dynamic_cast
. This is both more performant and doesn't violate OOP principles like dynamic_cast
does.