(1)static_cast:
它是一种主要用在基本类型转换和类类型转换之间。但是它们又有区别,具体看下面的例子:
基本类型转换:
大家都知道在基本数据类型转换的时候,高类型数据转低类型数据其实就是隐式转换,也是安全的,为什么呢?因为没有丢失精度,比如float a =1.234,转换成int b =a;,对于整型的int b 来说完全ok,因为没有任何损失,但是当低类型数据转换成高类型数据时就出现精度丢失,比如 int c =1,转换成float型的d时,小数点后面的数据就丢失,此时就需要大家常说的显示类型转换去进行强制类型转换,c =(float)d,此处也可以用static_cast,因为都是具体的静态数据,效果一样。
类类型:
此处稍微和基本类型有点区别,简单讲就是在继承关系中,子类型转父类型可以通过static_cast进行转换,但是父类型通过static_cast却不行。但是可以通过另一个方式进行转换,dynamic_cast,具体请看下面的(4)介绍。
(2)const_cast:
它是一种用来进行比较安全的、基于内容的数据类型转换,一般它的作用就是把数据类型中的const属性去掉,使之将常指针类型转换成普通指针,将常引用转换为普通引用。
eg:
void func( const int *p)
{
int * q = const_cast<int *>p;
(*q)++;
}
说明:正常情况下,const int *p 要求p指向的地址存储的值不能发生变化,表示常指针,但是此处通过const_cast把const性质去掉,导致对应地址的值变成了普通指针指向的值,从而可以进行修改。常引用转换普通引用也如此。
(3)reinterpret_cast:
它是用来在任意类型之间进行转换,具有很大的危险性和不确定性,它可以在任意指针之间进行互相转换,即使这些指针所指的内容是毫无关系的。因此这种使用应当在程序中是需要避免的。
(4)dynamic_cast:
它主要应用于类之间的转换。常说的类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
eg1:
class A
{};
clsss B : public A
{};
B b;
A *a =dynamic_cast<B*>(&b);
eg2:
class A
{};
class B :public A
{};
A *a =new B ;
A *b =new A;
B *c = dynamic_cast<B>a; (TRUE)
B *d =dynamic_castt<B>b; (FALSE)