Explains the differences between the four casts in C++

  • 2020-04-01 23:35:59
  • OfStack

C++ has four casts, so C++ is not type-safe. Static_cast, dynamic_cast, const_cast, reinterpret_cast, respectively
Why use a c-style cast to convert anything you want to a desirable type. So why do you need a new C++ cast?
The new type of cast provides better control over the cast process, allowing for the control of different kinds of casts. The style in C++ is static_cast < The type > (the content). Another benefit of C++ style casts is that they make it clearer what they are doing. A programmer can glance at such code and immediately know the purpose of a cast.
Differences of the four transformations:
Static_cast: converts between the built-in base data types in C++.

int c=static_cast<int>(7.987); 

If classes are involved, the static_cast can only be found in The types of relationships In the mutual conversion, does not necessarily contain virtual functions.

class A 
{}; 
class B:public A 
{}; 
class C 
{}; 

int main() 
{ 
    A* a=new A; 
    B* b; 
    C* c; 
    b=static_cast<B>(a);  //Compile without error, class B inherits class A
    c=static_cast<B>(a);  //Compile error, class C has nothing to do with class A
    return 1; 
}

Const_cast: the const_cast operation cannot be converted between different types. Instead, it simply converts an expression it ACTS on to a constant. It can convert data that is not of const type to const type, or remove the const attribute.
Reinterpret_cast: has the same ability as a c-style cast. It can convert any built-in data type to any other data type and any pointer type to any other type. It can even convert built-in data types into Pointers without regard to type safety or constants. Not unless you have to.
Dynamic_cast:
(1) the other three are done at compile time, while dynamic_cast is handled at run time, and type checking is performed at run time.
(2) cannot be used for casting of built-in basic data types.
(3) the dynamic_cast transform returns a pointer or reference to the class if it succeeds, and NULL if it fails.
(4) for conversion by dynamic_cast, there must be virtual functions in the base class, otherwise the compilation will not pass.
              B needs to detect the reason for the virtual function: the existence of a virtual function in a class indicates that it wants a base class pointer or reference to a derived class object, and the conversion makes sense.
              This is because runtime type checking requires runtime type information, which is stored in the virtual function table of the class < Inside the c + + object model > ),
              Only classes that define virtual functions have virtual function tables.
  (5) when a class is converted, the effect of dynamic_cast and static_cast is the same when the upstream conversion is carried out between the class levels. Dynamic_cast has the function of type checking when downcasting                             Static_cast is safer. The upcast is the downcast to the subclass object, which is the superclass pointer to the subclass pointer. The success of the downcast is also related to the type to be converted, that is, the actual type of the object to be converted must be the same as the type of the object to be converted, or the conversion will fail.
Reference examples:

#include<iostream> 
#include<cstring> 
using namespace std; 
class A 
{ 
   public: 
   virtual void f() 
   { 
       cout<<"hello"<<endl; 
       }; 
}; 

class B:public A 
{ 
    public: 
    void f() 
    { 
        cout<<"hello2"<<endl; 
        }; 

}; 

class C 
{ 
  void pp() 
  { 
      return; 
  } 
}; 

int fun() 
{ 
    return 1; 
} 
int main() 
{ 
    A* a1=new B;//A1 is A pointer of type A to an object of type B
    A* a2=new A;//A2 is A pointer to an object of type A
    B* b; 
    C* c; 
    b=dynamic_cast<B*>(a1);//The result is not null, and the downward conversion is successful. A1 was pointing to the object of type B before, so it can be converted to a pointer of type B.
    if(b==NULL) 
    { 
        cout<<"null"<<endl; 
    } 
    else
    { 
        cout<<"not null"<<endl; 
    } 
    b=dynamic_cast<B*>(a2);//The result is null and the downward conversion failed
    if(b==NULL) 
    { 
        cout<<"null"<<endl; 
    } 
    else
    { 
        cout<<"not null"<<endl; 
    } 
    c=dynamic_cast<C*>(a);//The result is null and the downward conversion failed
    if(c==NULL) 
    { 
        cout<<"null"<<endl; 
    } 
    else
    { 
        cout<<"not null"<<endl; 
    } 
    delete(a); 
    return 0; 
}

Related articles: