c++ static_cast and references
Solution 1
From standard n3337 draft 5.2.9/2
An lvalue of type “cv1 B,” where B is a class type, can be cast to type “reference to cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D.
In your case:
B
is class derived from A
, both are non-const, and conversion from A*
to B*
is allowed, A
is not virtual base class of D
.
Solution 2
static_cast<>
will only check if the types are compatible
In case 1 types are not directly compatible since the re is no operator to describe the copy relation between A and B
In case 2 the cast is a reference cast and as far as the compiler is concerned A*
can be casted to B*
because they are compatible. The compiler will not know what the pointer a_ref
holds so that's why it allows you to use it. dynamic_cast<>
checks the class the pointer points to also.
Solution 3
This is one of the reasons why I use boost::polymorphic_downcast
(doc) - in debug it uses dynamic_cast
followed by assert and in release it is static_cast
, so no performance hit.
Solution 4
(*2) compiles fine, but why?
In general, you can't check the dynamic type statically; and static_cast
doesn't do any dynamic type checking. It allows any conversion that might be valid according to the static types, including conversions that aren't valid according to the dynamic types.
what if i cast a_ref to B& and then try to access the attributes?
Undefined behaviour. If you use static_cast
, then the onus is on you to make sure the conversion is valid.
How do i have to deal with such situation where i need to cast references and be sure that i really get the right references.
For polymorphic types, use dynamic_cast
. Applied to a reference, it will throw std::bad_cast
if the conversion is not valid.
For non-polymorphic types, you're on your own.
Related videos on Youtube
fogbit
Updated on June 04, 2022Comments
-
fogbit almost 2 years
struct A{}; struct B : A{}; int main() { A a; A& a_ref = a; static_cast<B>(a); // *1 static_cast<B&>(a_ref); // *2 return 0; }
(*1) produces an error and i understand why. (*2) compiles fine, but why? And, as long as it compiles and suppose
B
contains some attributes, what if i casta_ref
toB&
and then try to access the attributes? I think i will have an run-time error or something.So, as i can see, there is a situation which leads to crash and there are no ways to avoid it, unlike with
dynamic_cast
where one can check the result of casting for null or put code in atry-catch
region. How do i have to deal with such situation where i need to cast references and be sure that i really get the right references. -
fogbit over 10 yearsthanks for the info, i'll check
boost::polymorphic_downcast