c++有两种强制转换:1、命名的强制转换 2、旧式的强制类型转换
1、命名的强制转换
形式:cast-name(expression);
type是要转换成的目标类型,expression是要转换的值
cast-name关键字有:static_cast, reinterpret_cast,const_cast,dynamic_cast
cast-name指定了执行的是哪种转换。
static_cast:任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_const,(对象本身是常量,那就是顶层const,否则就是底层const)
较大算术类型赋值给较小的类型时,static_cast非常有用
static_cast对于无法自动执行的类型转换也很有用,譬如可以用static_cast找回存在void*指针中的值:
void* p=&d;
double* dp=static_cast<double*>(p);
reinterpret_cast:
通常为运算对象的位模式提供较低层次上的重新解释,如果被转换的两种类型之间不相关,比如int指针转换为char指针,就要使用reinterpret_cast这个关键字。
注意,使用reinterpret_cast是非常危险的,譬如把int*转化为char*,使用reinterpret_cast显示声明合法,编译器接下来就会认为其就是char*类型的,把它当做char*类型的去使用可能造成糟糕的后果。
const_cast:只能改变对象的底层const,去掉表达式的常量属性,使用const_cast会消除被转换类型的const特性,而且只有const类型的变量才能使用。那么,什么情况下需要消除一个const变量的const特性呢?比如,有时候有的函数的形参类型为非const类型,那么如果你要将一个const类型的参数传入就会报错。所以在这种情况下需要先使用const_cast转化一下。
dynamic_cast:它是一种作运行时(run-time)检测的类型转换。它可以将基类类型的指针或引用安全地转换为派生类型的指针或引用。当具有基类的引用或指针,但需要执行不是基类组成部分的派生类操作的时候,需要动态的强制类型转换。通常,从基类指针获得派生类行为最好的方法是通过虚函数。当使用虚函数的时候,编译器自动根据对象的实际类型选择正确的函数。但是,在某些情况下,不可能使用虚函数。这时候就需要使用dynamic_cast关键字了。但是,能用虚函数还是用虚函数最好。
与其他强制类型转换不同,dynamic_cast涉及运行时类型检查。如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。
补充:
在上面四个类型转化关键字中,除了static_cast,其他的三个都有可能涉及到指针的类型转换。从本质上来说,指针的类型不同,并没有产生很大的差异,他们都是需要足够的内存来存放一个机器地址。“指向不同类型之各指针”间的差异,既不在其指针表示法不同,也不在其内容(代表一个地址)不同,而是在其所寻址出来的object不同。也就是说,“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小。
所以,转换(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响“被指出之内存大小和其内容”的解释方式。
2、旧式的强制类型转换
type (expr);
(type) expr;
根据所涉及的类型不同,旧式的强制类型转换具有与static_cast,reinterpret_cast,const_cast相似的行为