文章目录
-
- C语言中的类型转换
-
- 隐式类型转换
- 显示类型转换(强制类型转换)
- C++强制类型转化
-
- static_cast
- reinterpret_cast
- const_cast
- dynamic_cast
- explicit
C语言中的类型转换 C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化
C语言中总共有两种形式的类型转换:
隐式类型转换
和显式类型转换
。隐式类型转换
编译器在
编译阶段自动进行
,能转就转,不能转就编译失败适用于相近的类型
void show(int i){
//参数的接收发生了隐式类型转换
std::cout << i << std::endl;
}
int main(){
double d = 1.1;
show(d);
return 0;
}
显示类型转换(强制类型转换)
需要用户自己处理
,通常用于不相近类型的转换int main(){
int a = 0;
int* p = &a;
//将指针强制转化为int类型
int b = (int)p;
}
C++强制类型转化 C语言的类型转化有很大的缺陷:
- 隐式类型转换可能会因为整形提升或者数据截断导致
精度的丢失
- 隐式类型有时会被程序员
忘记
或者忽略
,造成错误 - 显式类型转换将所有情况混合在一起,
代码不够清晰
,如果出现错误不好查
为了加强类型转化的
规范性和可视性,引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast、dynamic_cast
static_cast
static_cast
用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换
。(即对应C语言中的隐式类型转换
)int main(){
double d = 1.1;
//可以让隐式类型转化更加规范
int a = static_cast(d);
std::cout << i;
}
reinterpret_cast
reinterpret_cast
是一种较为危险的类型转换,通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型,通常适用于指针、引用、以及整数之间的类型转换。对应C语言的强制类型转化
int main(){ int a = 998;
int* p1 = &a;
//这里的强制类型转化,是把int指向的空间强制转化成了double指向的空间
//所以p1以前读取四个字节内容,转换后p2可以读取八个字节内存,所以p1在转换后指向的内容发生了变化
double* p2 = reinterpret_cast(p1);
std::cout << *p2 <::endl<< *p1;
}
文章图片
const_cast
通常用于删除变量的const属性
int main(){
//const变量会被编译器优化放到寄存器,加上volatile防止编译器优化
volatile const int a = 2;
int* p = const_cast(&a);
*p = 3;
std::cout << a << std::endl;
std::cout << *p << std::endl;
return 0;
}
dynamic_cast
【C++|【C++】类型转换】将基类的指针或引用
安全地
转换成派生类的指针或引用基类和派生类之间的转换分为两种
- 向上转型:子类对象指针/引用->父类指针/引用(
切片
,原生支持
的) - 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是
安全的
)
dynamic_cast的向下转换``只支持
继承中的多态类型,也就是父类之中必须包含虚函数class A {
public:
virtual void f() = 0;
};
class B : public A{
public:
virtual void f() {
cout << "f()::B" << endl;
} void showB() {
cout << "showB()::B" << endl;
}
};
int main() {
A* pa = new B;
//把基类指针强制转换为派生类指针
B* pb = dynamic_cast(pa);
//转换时会做安全检查,如果不能成功转换就会返回0
if (pb) {
pb->showB();
}
return 0;
}
dynamic_cast
只能用于含有虚函数的类dynamic_cast
会先检查是否能转换成功,能成功则转换,不能则返回0
explicit关键字
用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换
class A{
public:
explicit A(int a){
cout << "A(int a)" << endl;
}
private:
int _a;
};
int main(){
A a1(1);
// 隐式转换-> A tmp(1);
A a2(tmp);
A a2 = 1;
}
文章图片
a2使用赋值进行初始化
,其实是先把1隐式类型转换为一个临时对象
,然后用临时对象对a2进行赋值
使用explicit关键字修饰构造函数,
A就不会进行隐式类型转换
推荐阅读
- C++提高编程|2. STL初识
- 笔记|C++(继承和派生)
- c++|C++(从零开始,万字模拟实现string(超详细))
- 学习|C++ 练习3 [牛客]
- python|第二十九(如何搭建数据驱动自动化测试框架(粗糙))
- python|Python如何实现人脸识别系统
- LeetCode高频面试题|LeetCode 416. 分割等和子集 【c++/java详细题解】
- LeetCode高频面试题|剑指 Offer 59 - I. 滑动窗口的最大值 【c++/java详细题解】
- LeetCode高频面试题|LeetCode 213. 打家劫舍 II【c++/java详细题解】