c++ static_cast and references

15,256

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.

Share:
15,256

Related videos on Youtube

fogbit
Author by

fogbit

Updated on June 04, 2022

Comments

  • fogbit
    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 cast a_ref to B& 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 a try-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
    fogbit over 10 years
    thanks for the info, i'll check boost::polymorphic_downcast