一文详解C++中的类型转化
1. C语言中的类型转换在C语言中如果赋值运算符左右两侧类型不同或者形参与实参类型不匹配或者返回值类型与接收返回值类型不一致时就需要发生类型转化C语言中总共有两种形式的类型转换隐式类型转换和显式类型转换。1. 隐式类型转化编译器在编译阶段自动进行能转就转不能转就编译失败2. 显式类型转化需要用户自己处理举个例子12345678910111213141516intmain(){doublei 4.2;//隐式类型转化inta i;//显示的强制类型转换intb (int)i;int*paintd(int)p;cout i endl;cout b endl;cout a endl;cout d endl;}那为什么还要出现C中的类型转换呢因为C语言中的隐式类型转换会带来很多问题比如123456789intmain(){inti 0;size_tsize 5;while(size i){size--;}}size是无符号整型i是int在操作符两端的类型就会发生整型提升导致size永远大于0造成死循环。所以C出了一套类型转化的规范写法。隐式类型转化有些情况下可能会出问题比如数据精度丢失显式类型转换将所有情况混合在一起代码不够清晰因此C提出了自己的类型转化风格注意因为C要兼容C语言所以C中还可以使用C语言的转化风格。2. C强制类型转换static_castreinterpret_castconst_castdynamic_cast这是c规范的四种类型转化。1. static_cast2.reinterpret_cast3.const_cast我们来看一个例子123456789intmain(){constinta 2;int* p const_castint*(a);//去掉const属性*p 5;cout a endl;cout *p endl;return0;}大家可以猜一下结果是什么可能有人会想这不是改变了吗为什么还是2呢原因是在编译时因为是const修饰不会修改所以就会把a的值放入寄存器中通过*p来改变的是内存中的a的值但是a在寄存器中的值没有改变依旧是2所以打印时就是2。为了防止这种优化行为的发生就会在a的前面加volatile const int a2;表明了a的值会改变不要放在寄存器中所以每次去取a的值就会到内存中去取。保持内存可见性就因为const_cast会导致这种危险行为的发生所以C就会把const_cast这个类型转化单独拿出来但用的时候很危险可以看出const_cast取消了const属性。4.dynamic_cast这种类型转化是专门来针对父类和子类指针之间的相互转化的dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用 (动态转换)向上转型子类对象指针/引用-父类指针/引用(不需要转换赋值兼容规则天然的一种行为)向下转型父类对象指针/引用-子类指针/引用(用dynamic_cast转型是安全的)注意1. dynamic_cast只能用于父类含有虚函数的类2.dynamic_cast会先检查是否能转换成功能成功则转换不能则返回0如果我们不使用dynamic_cast来进行向下转型父类转化为子类那就会发生越界的情况123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657classA{public:virtualvoidf() {}int_a 0;};classB :publicA{public:int_b 0;};//C语言中的强转//void Func(A* ptr)//{// // 直接转换是不安全的// B* bptr (B*)ptr; //父类转子类// cout bptr endl;//// bptr-_a;// bptr-_b; //发生越界//// cout bptr-_a endl;// cout bptr-_b endl;//}voidFunc(A* ptr){// C规范的dynamic_cast是安全的// 如果ptr是指向父类则转换失败返回空// 如果ptr是指向子类则转换成功B* bptr dynamic_castB*(ptr);cout bptr endl;if(bptr){bptr-_a;bptr-_b;cout bptr-_a endl;cout bptr-_b endl;}}intmain(){A aa;B bb;Func(aa);Func(bb);return0;}总结这就是C中的四种类型转化但是强制类型转换关闭或挂起了正常的类型检查每次使用强制类型转换前程序员应该仔细考虑是否还有其他不同的方法达到同一目的如果非强制类型转换不可则应限制强制转换值的作用域以减少发生错误的机会。 强烈建议避免使用强制类型转换