一、C语言中的类型转换
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;
这是一种不安全的转换,强制转换可能会出现高类型转换为低类型的情况,数据精度受到损失
二、c++中的强制类型转换
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的好用,依个人所爱使用,最重要的是要写好代码,希望对大家有所帮助。
时间: 2024-11-11 15:55:33