static_cast ,dynamic_cast,const_cast,reinterpret_cast
static_cast
定义:通俗的说就是静态显式转换,用于基本的数据类型转换,及指针之间的转换,当需要把一个较大的算术类型赋值给较小的类型时,这个转换非常有用,任何具有明确定义的类型转换,只要不包含const,
都可以使用static_cast,格式如:static_cast<type-id>(expression),意为expression转换成type-id,但没有类型检查来保证转换的安全性
使用:(1) 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类是表示)是安全的;子类的对象一般比基类大
这就是为什么基类指针可以指向并创建一个子类对象,但子类指针不能指向基类对象,即是因为上行转换是安全的,下行转换有风险
(2) 进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的
(3) 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等等,这种转换的安全性由开发人员来保证
(4) 把void指针转换成目标类型的指针(不安全!),因为已经分配了内存,在更换目标类型的时候可能因为内存导致程序崩溃
(5) 把任何类型的表达式转换成void类型
注意:static_cast不能转换掉expression的const,volitale,或者__unaligned属性
例如:int i = 0x7fff;long l;float f;
l = static_cast<long>(i);
i = static_cast<int>(l);
//以及把子类指针转换成基类指针等
dynamic_cast
定义:是用来执行继承体系中“安全的向下转型或跨系转型动作”,使用格式同static_cast,在进行下行转换时可以得知转型是否成功,如果转失败的是指针,那么会以一个null指针形式表现出来,如果是引用
那么会以一个expression表现出来
dynamic_cast与static_cast区别:static_cast全部用于明确定义的变换,包括编译器允许我们所做的不用强制转换的安全变换和不太安全但清楚定义的变换,
在进行类型间上行转换时,其和static_cast的效果是一样的,在进行下行转换时比static_cast更安全
例子:
class B {
public:
int m_iNum;
virtual void foo();
};
class D:public B {
public:
char *m_szName[100];
}
void func(B *pb) {
D *pd1 = static_cast(pb);
D *pd2 = dynamic_cast(pb);
}
在上面的代码中,如果pb指向一个D类型的对象,pd1和pd2是一样的,并且对这两个指针执行D类型的任何操作都是安全的,因为它本身就是D类型的,所以没问题,而如果pb指向的是一个B类型的对象
那么pd1将是一个指向该对象的指针(不管是否有风险),对它进行D类型的操作将是不安全的(如访问m_szName),而pd2将是一个空指针,注意dynamic_cast转换时,B(基类)需要有虚函数,否则会编译出错
static_cast则没有这个限制,这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚表中
const_cast
定义:对“const”和“volatile”进行转换,最常见的用途就是将某个对象的常量性去掉,使用其他类型转换表达式的const属性都将引发编译器编译错误
例子:const char *pc; char *p = cosnt_cast<char *>(pc);//这种转换不能改变表达式的类型
reinterpret
转换为完全不同的意思,为了安全使用它,关键必须转换为原来的类型。转换成的类型一般只能用于位操作,否则就是为其他隐秘的目的,这是所有转换中最危险的,且跟平台有密切关系