Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ static_cast and references

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.

like image 808
fogbit Avatar asked Oct 30 '13 13:10

fogbit


2 Answers

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.

like image 164
ForEveR Avatar answered Oct 27 '22 04:10

ForEveR


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.

like image 22
Raxvan Avatar answered Oct 27 '22 04:10

Raxvan