问题:c函数的强制类型转换过于粗暴,容易引发不可知的错误,而且不容易在代码中定位。
举例:
typedef void(PF)(int); //定义一个函数类型
int main(void)
{
int a = 0x12345;
PF* pfunc = (PF*)a; //定义一个函数指针pfunc,指向地址0x12345
pfunc(1); //由于0x12345并非真正存在函数,故执行时会出现段错误
}
解决:c++提供新的4种强制类型转换,更加安全可靠。优点:
编译器可帮助检查潜在问题;方便在代码中定位;支持动态类型识别(dynamic_cast)。
(当出现强制转换错误的时候,只要搜索下面四种关键字,即可快速定位到所有强制转换的地方,便于排查问题)
c++强制类型转换
种类:
static_cast //静态类型转换
//用于基本类型间转换(如int double char等)
//不能用于基本类型指针间转换
//用于有继承关系对象之间的转换和类指针之间的转换(类的概念以后再说)
const_cast //用于去除变量的只读属性
//强制转换的目标类型必须是指针或引用
dynamic_cast //动态类型转换(后期再深入研究)
//用于有继承关系的类指针间的转换
//用于有交叉关系的类指针间的转换
//具有类型检查功能(如果转换不成功的话,最终得到的是空指针)
//需要虚函数的支持
reinterpret_cast //用于指针类型之间的强制转换
//用于整数和指针类型间的强制转换
//不能用于基本类型之间的转换
用法:
xxx_cast <Type> (Expression)
说明: Type 目标类型
Expression 运算式
举例1. (static_cast)
int i = 0x12345;
char c = 'c';
int* pi = &i;
char* pc = &c;
c = static_cast<char>(i); //将int型的i值强制转换为char型
pc = static_cast<char*>(pi); //这句错误,因为static_cast不支持基本类型指针间的转换
举例2. (const_cast)
const int& j = 1; //定义了一个只读变量j(编译器分配一个地址空间,其引用(别名)为j,其初始值为1)
int& k = const_cast<int&>(j); //const_cast强制将j的只读属性去掉,这样就可用k引用(别名)直接修改j的值
const int x = 2; //定义了一个只读常量
int& y = const_cast<int&>(x); //这里const_cast转换的其实是编译器为x常量另外分配的存储空间。
//所以通过y引用能修改的只是分配的存储空间,而非x常量本身
int z = const_cast<int>(x); //这句错误,因为const_cast只能用于引用或指针之间的转换。
举例3. (reinterpret_cast)
int i=0; char c = 'c';
int* pi = &i; char* pc = &c;
pi = reinterpret_cast<int*>(pc); //基本类型指针之间的转换
pi = reinterpret_cast<int*>(i); //整型和指针类型之间的转换
c = reinterpret_cast<>(i); //这句错误,因为reinterpret_cast不支持基本类型之间的转换
举例4. (dynamic_cast)
int i = 0;
int* pi = &i;
char* pc = dynamic_cast<char*>(pi); //这句错误,dynamic_cast用于类指针之间的强制类型转换,而且类指针指向的对象所属的类还必须有虚函数的支持。