Is this static_cast
downcast valid?
// non-virtual, may be non-trivially copyable
struct Base{
int m_object;
};
// Derived class have only non-virtual functions
struct A : Base{
void arggh(){
std::cout << "Arrghh " << m_object;
}
};
int main() {
Base base{190};
A& a = static_cast<A&>(base);
a.arggh();
return 0;
}
I mean, CREATE base class, and then cast to derived.
Live
static_cast
for performing downcast does not perform any safety checks. Since it's possible for a Base&
to be referencing an instance of A
, the cast proceeds and since it's NOT actually referencing an A
, we enter undefined behavior territory*.
A dynamic_cast
on the other hand is safer. It will perform a check and throw an exception in the case of reference casting, or return nullptr
in the case of pointer casting†.
However, since your base class lacks any virtual functions, dynamic_cast
is impossible, so you'd need to modify it with at least a virtual destructor:
class Base{
public:
int m_object;
virtual ~Base()=default;
};
Now if we tried to cast:
A* a = dynamic_cast<A*>(&base);
if (a)
a->arggh();
else
std::cout << "null\n";
Our output would be
null
*Relevant standardese can be found in [expr.static.cast]:
[for a cast like
static_cast<D&>(b)
whereb
is an instance of a base class forD
], If the object of type “cv1B
” is actually a base class subobject of an object of typeD
, the result refers to the enclosing object of typeD
. Otherwise, the behavior is undefined.
†Relevant standardese at [expr.dynamic.cast]
The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throws an exception of a type that would match a handler of type
std::bad_cast
No.
Not all Base
objects are of type A
1, although the converse is true, and a static_cast
would work in that direction.
1Another translation unit might have a class that inherits from Base
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With