昆明建站网站资讯平台个人购物网站 怎么建
张小明 2025/12/23 14:32:35
昆明建站网站资讯平台,个人购物网站 怎么建,wordpress cdn优化,百度竞价专员目录 c的类型转换
1. C语言中的类型转换
2. 为什么c需要四种类型转换
3. c强制类型转换解析
3.1 static_cast
3.2 reinterpret_cast
3.3 const_cast
3.4 dynamic_cast
4. RTTI c的类型转换
c语言和c是一个强类型的语言#xff0c;也就是变量和变量之间有明显的类型的…目录c的类型转换1. C语言中的类型转换2. 为什么c需要四种类型转换3. c强制类型转换解析3.1 static_cast3.2 reinterpret_cast3.3 const_cast3.4 dynamic_cast4. RTTIc的类型转换c语言和c是一个强类型的语言也就是变量和变量之间有明显的类型的区分1. C语言中的类型转换在C语言中如果赋值运算符左右两侧类型不同或者形参与实参类型不匹配或者返回值类型与接收返回值类型不一致时就需要发生类型转化C语言中总共有两种形式的类型转换隐式类型转换和显式类型转换。1. 隐式类型转化编译器在编译阶段自动进行能转就转不能转就编译失败2. 显式类型转化需要用户自己处理缺陷转换的可视性比较差所有的转换形式都是以一种相同的形式书写难以跟踪错误转换2. 为什么c需要四种类型转换标准C为了加强类型转换的可视性引入了四种命名的强制类型转换操作符static_cast、reinterpret_cast、const_cast、dynamic_castC风格的转换格式很简单但是有不少缺点的1. 隐式类型转化有些情况下可能会出问题比如数据精度丢失2. 显式类型转换将所有情况混合在一起代码不够清晰因此C提出了自己的类型转化风格注意因为C要兼容C语言所以C中还可以使用C语言的转化风格c兼容c语言留下来的隐式类型转换和显示转换但是c觉得c语言做的不规范c想规范一下标准c为了加强类型的可视性引入了四种命名的强制类型转换操作符3. c强制类型转换解析3.1 static_cast对于c语言中的隐式类型转换相近的类型就使用这个int i 1; double d 8.88; i static_castint(d); cout i endl;3.2 reinterpret_cast对于c语言中的强制类型转换不相近的类型就用这个int i 1; double d 8.88; i static_castint(d); cout i endl; int* p nullptr; p reinterpret_castint*(i); cout p endl;总结如果你不相近的类型使用了static_cast就不可以如果相近的类型使用了reinterpret_cast也不可以总之c是为了实现你一看用哪个cast就知道但注意你并没有改变原来变量的类型也就是d还是8.88还是double类型3.3 const_castconst_cast就是去除const属性的const int ci 10; int* pi const_castint*(ci); *pi 20; cout *pi endl; cout ci endl;这种情况是未定义行为原变量是const修饰的但是经你这么修改原变量本来是const但是可以通过指针来修改这种是不合法的结果是未定义的// 可能的结果 // 1. 程序崩溃 // 2. 输出 ci 仍为 10编译器优化a 被存储在只读内存/寄存器 // 3. 输出 ci为 20极少数未优化场景。我的编译器优化之后ci仍然为10原因可以看到通过调试已经修改了变量的值但是为什么打印ci是10这是是去寄存器当中找的就是因为你原来是const对象它认为你是不可能修改的所以放到寄存器当中这样速度快但是你这里修改的是内存当中的值ci当中内存是变20了然后打印的时候由于ci寄存器有直接就拿了本质是由于编译器对const对象存取优化机制导致的甚至有些直接优化成常量10了为了避免编译器优化可以通过加volatile关键字让编译器每次都到内存当中取volatile const int ci10;但是一般不要这么编写本来好好的const常量被你修改了之后能变一般都是const指针或者const引用去除const属性只有这种场景是合法的3.4 dynamic_cast用于多态类型的转换c中子类对象可以赋值给父类的对象、指针、引用、这个过程是语法天然支持的可以成功https://blog.csdn.net/Laydya/article/details/148145002dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)向上转型子类对象指针/引用-父类指针/引用(不需要转换赋值兼容规则) 向下转型父类对象指针/引用-子类指针/引用(用dynamic_cast转型是安全的)注意 1. dynamic_cast只能用于含有虚函数的类 2. dynamic_cast会先检查是否能转换成功能成功则转换不能则返回0class A { public: virtual void f() {} int _a; }; class B :public A { public: int _b; }; void f_cast(A* pa) { //如果想要区分pa是指向父类还是子类对象 B* pb (B*)pa; pb-_a 1; pb-_b 2; } int main() { A a; B b; A* pa a; f_cast(pa); B* pb b; f_cast(pb); return 0; }这里强制类型转换了之后其实就是这个pb指针能看到的东西更多了也就是指针的意义就是根据类型能够看到多大的空间由于你原来是A的类型但是你这里强制类型转换成b了所以看到的东西变多了然后你pb- _b 就会越界访问如果你本身就是一个子类对象那就没问题因为你本身就可以看到这么多东西class A { public: virtual void f() {} int _a; }; class B :public A { public: int _b; }; void f_cast(A* pa) { //如果想要区分pa是指向父类还是子类对象 B* pb dynamic_castB*(pa); if (pb ! nullptr) { cout 转换成功 endl; pb-_a 1; pb-_b 2; } else { cout 转换失败 endl; } } int main() { A a; B b; A* pa a; f_cast(pa); B* pb b; f_cast(pb); return 0; }使用dynamic_cast如果pa是指向子类对象则转换成功反之如果是父类对象则转换失败注意只能针对继承中的多态类型父类必须包含虚函数如果你把A里面的虚函数去掉那就编译不过去了原理dynamic_cast通过去虚表的上方存储的标识信息来判断指向父类对象还是子类对象如果没有虚函数则没有虚表就无法判断了总结尽量少用类型转换如果要用就用规范一些让别人一看到就知道你在干嘛4. RTTIRTTIRun-Time Type Information运行时类型信息是 C 提供的在程序运行阶段获取对象 / 指针实际类型信息的机制核心作用是打破编译期的类型绑定让程序在运行时识别多态类型比如基类指针指向的派生类对象的真实类型。C 标准中RTTI 的支持是可选的但主流编译器如 GCC/Clang/MSVC 均默认开启且仅对带有虚函数的类多态类能正确返回动态类型非多态类的 RTTI 仅能返回编译期类型。C通过以下方式来支持RTTI1.typeid运算符typeid运算符返回std::type_info对象包含类型的名称、哈希值等信息可用于比较两个对象 / 指针的实际类型是否相同获取类型的名称注意名称格式由编译器决定不一定是类的原名。只有多态才能返回指向的类型如果没有多态返回的是编译期类型基类而非实际指向的派生类2.dynamic_cast运算符这个上面已经做了详细的讲解也就是通过运行时的类型确定的运行起来后通过查虚表虚表里面有标识来辨别实际类型仅仅针对多态