【C++】C++中的类型转换
🚀write in front🚀
📜所属专栏: C++学习
🛰️博客主页:睿睿的博客主页
🛰️代码仓库:🎉VS2022_C语言仓库
🎡您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!
关注我,关注我,关注我,你们将会看到更多的优质内容!!
文章目录
- 前言
- 一.回忆C语言的类型转换:
- 缺陷:
- 二.C++强制类型转换:
- 1.static_cast:
- 2.reinterpret_cast
- 3.const_cast:
- 4.dynamic_cast:
- 三.RTTI(了解)
- 总结
前言
在平常的学习中,类型的转换其实是不断在出现的,那么C++11相比于C语言的类型转换又有了哪些不同呢?这篇文章就来教会你C++里面的类型转换
一.回忆C语言的类型转换:
在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。
- 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
- 显式类型转化:需要用户自己处理
void Test ()
{
int i = 1;
// 隐式类型转换
double d = i;
printf("%d, %.2f\n" , i, d);
int* p = &i;
// 显示的强制类型转换
int address = (int) p;
printf("%x, %d\n" , p, address);
}
不知道大家是否还记得C语言里面的一个大坑:
void insert(size_t n, char ch)
{int end = 10;while (end >= n){cout << end << endl;end--;}
}int main()
{insert(0,'ch');
}
这段代码看上去感觉没有什么问题,但是当传的pos为0的时候,就会死循环,这就是隐式类型转化所导致的(int要转化为size_t,此时如果int为负数也会被转化为正数).
缺陷:
转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换
二.C++强制类型转换:
标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符
static_cast
、reinterpret_cast
、const_cast
、dynamic_cast
这里的操作符的调用有点像函数对象调用函数 (哈哈哈)
1.static_cast:
static_cast
用于非多态类型的转换(静态转换),只适用于相关类型/相近类型的转换,比如将int
存到double
里面
int a = 0;//C语言://double d = a;//double d=(double)a;//C++:double d = static_cast<int>(a);
2.reinterpret_cast
reinterpret_cast
主要用于不相关类型之间的转换,比如将地址保存到整形:
int* p1 = &a;//C语言:// int address = (int)p1;//C++int address = reinterpret_cast<int>(p1);
3.const_cast:
const_cast
最常用的用途就是删除变量的const属性,方便赋值:
//这里的n没有去内存取,可能是宏替换或者寄存器里取出来面// const int n = 10;// volatile 修饰的变量,每次都要去内存取volatile const int n = 10;//C语言:(C语言指针类型都能强转)//转换有安全隐患//int *p2=(int*)&n;//C++:int* p2 = const_cast<int*>(&n);(*p2)=100;cout << "n:" << &n << " : " << n << endl;cout <<"p2:"<<p2<< " : " << *p2 << endl;
这里注意的是,一定要加一个volatile关键字,让每次都去内存里面取,不然会出问题(相同地址但是值不同)。
4.dynamic_cast:
dynamic_cast
用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
在之前继承的学习里面,我们学习了向上转换,是天然支持的,因为他的赋值兼容规则,只需对子类进行切片就可得到父类。
但是对于向下转换,由于指针是可以强行转化的,所以如果子类指针指向父类是没有错的,但是下面如果有调用成员,就会出问题(父类怎么调子类的成员,他根本没有)。所以为了使转化安全,就使用了dynamic_cast
。
class A
{
public:virtual void f() {}int _x = 0;
};class B : public A
{
public://int _y = 0;
};void fun(A* pa)
{// pa是指向子类对象B的,转换可以成功,正常返回地址// pa是指向父类对象A的,转换失败,返回空指针B* pb = dynamic_cast<B*>(pa);if (pb){cout << "转换成功" << endl;pb->_x++;//pb->_y++;}else{cout << "转换失败" << endl;}
}int main()
{A aa;fun(&aa);B bb;fun(&bb);
}
其实简单的说,dynamic_cast
就是杜绝了向下转换的发生。如果转换失败,就置为空。
三.RTTI(了解)
RTTI
:Run-time Type identification的简称,即:运行时类型识别。
C++通过以下方式来支持RTTI:
- typeid运算符
- dynamic_cast运算符
- decltype
总结
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!
专栏订阅:
每日一题
C语言学习
算法
智力题
初阶数据结构
Linux学习
C++学习
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!