1.隐式类型转换
int i = 1;
double d = i;
操作数的类型可以由低级转化为高级,这种隐式的类型转化是一种保值映射,即在转化中数据精度不损失。
类型高低顺序:
int(short和char自动转换成int)->unsigned->long->unsigned long->double(float自动转化成double型)
2.显示类型强制转换
int i = 1;
char a = (char )i;
int *p = &i;
int address = (int )p;
这是一种不安全的转换,强制转换可能会出现高类型转换为低类型的情况,数据精度受到损失
static_cast reinterpret_cast const_cast dynamic_cast
1.static_cast
用于非多态的类型转换(静态转换),不能用于两个不相关的类型进行转换
int i=1;
double d = static_cast<double>(i);
static_cast相当于一个类,<double>为一个模板类型,i是传入的构造函数的参数
2.reinterpret_cast
reinterpret_cast 是将一种类型转化为一种不同的类型
typedef void(*FUN)();
int DosSomething(int i)
{
return 0;
}
int main()
{
FUN f = reinterpret_cast<FUN>(DosSomething);
/*DoSomething函数返回值类型为int,参数为int类型,而FUN函数均为空
,所以虽然可以使DoSomething函数转化为FUN函数类型,但是不可移植,
不建议这么做。
*/
f();
}
3.const_cast
去常性转换,删除变量的const属性
int main()
{
volatile const int a = 2;
/*
若不加volatile则输出a=2。由于a是常性所以a优化后放到在寄存器中,后面
p虽指向且看起来似乎改变了a,但是在CPU取值时,a仍未改变。加上volatile
后取消了优化所以输出a=3。
*/
int *p = const_cast<int *>(&a);
*p = 3;
cout << a;
getchar();
}
ps: volatile即易变的、不稳定的,它告诉编译器,它后面的值是可能发生改变的,每次使用的时候必须从内存中去取
4.dynamic_cast
用于将一个子类对象的指针转换为父类对象的指针或引用(子类对象->父类指针、引用不需要转换)
1.dynamic_cast智能用于含虚函数的类
2.dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0;
class A
{
int _a;
};
class B :public A
{
int _b;
};
int main()
{
A a;
B b;
//b = a;//error
//b = (B)a;//error,父类给子类,强制转换也不行
A *pa = &a;
B *pb = &b;
//pb = pa;//error
pb = ( B*)pa;//可以强制转换,但是指向了非法的空间
//pb->_b = 10;//error,pb是由父类指针转换得到,它不能指向子类中不属于父类的部分
}
explicit:防隐式类型转换
string s2("asd");
string s1 = "acxs";
/*隐式转换,先用“acxs”调用构造函数构造了一个临时对象,再用拷贝构造函数创建对象s1
若在string类的构造函数前加上explicit则无法隐式转换,且这种隐式转换仅适用于单参数的
*/
以上为我所总结的类型转换的内容,个人觉得除了C++中的dynamic_cast比较能用上,其余三个的类型转换不如c的好用,依个人所爱使用,最重要的是要写好代码,希望对大家有所帮助。
转载于:https://blog.51cto.com/10797127/1761700