一、static_cast:任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。double slope = static_cast<double>(j)/i;
static_cast对于编译器无法自动执行的类型转换也是非常有用的。例如使用static_cast找回存在于void*指针中的值。
void* p= &d;//正确,任何非常量对象的地址都能存入void*
double *dp = static_cast<double*>(p);//正确,将void*转换回初始的指针类型
二、const_cast:只能改变运算对象的底层const,即将const类型的指针转换为非const类型的指针。
const char *pc;
char *p = const_cast<char *>(pc);//正确:但是通过p写值是未定义的行为
对于将常量对象转换成非常量对象的行为,一般称之为去掉const性质。一旦去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。
三、reinterpret_cast:为数据的二进制形式重新解释,但是不改变其值。
四、dynamic_cast:其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。
(2)不能用于内置的基本数据类型的强制转换。
(3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。
(4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
需要检测虚函数的原因:类中存在虚函数,即说明它有想要将基类指针或者引用指向派生类对象的情况,此时的转换才有意义。
BaseClass *pb = new DerivedClass();
DerivedClass *pd1 = static_cast<DerivedClass *>(pb);
//子类->父类,静态类型转换,正确但不推荐
DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb);
//子类->父类,动态类型转换,正确
BaseClass *pb2 = new BaseClass();
DerivedClass *pb21 = static_cast<DerivedClass *>(pb2);
//父类->子类,静态类型转换,危险。访问子类m_szName成员越界
DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2);
//父类->子类,动态类型转换,安全的,结果是NULL
总结:
1、去const属性用const_cast
2、基本类型转换用static_cast
3、多态类之间的类型转换用dynamic_cast
4、不同类型的指针类型转换用热interpret——cast