博客原文:https://blog.csdn.net/qq_39412582/article/details/82392147 原文更加详细哦
我们先来看一看以前是怎么定义数据类型转换的:
#include <iostream>
using namespace std;
void Test()
{
//隐式的类型转换
int i = 10;
double d = i;
printf("%d ,%.2f\n", i, d);
//显式的强制类型转换
int* p = &i;
int address = (int)p;
printf("%x ,%d\n", p, address);
}
int main()
{
Test();
return 0;
}
{:--}
这种转换有一个缺陷就是:强制转换可视效果差,所有的转换形式都是同一种形式书写,如果出现错误,不容易跟踪错误的转换。
为了解决强制转换带来的可视化效果差的问题引入了四种命名的强制类型转换操作符:static_cast,reinterpret_cast,const_cast,dynamic_cast 四个操作符你见过几个?哈哈哈,没见过也没关系,我也没见过几个。下面我仔细地解释这四个操作符:
• static_cast static_cast用于非多态类型的转换(也叫静态转换),编译器隐式执行的任何类型转换都可以用static_cast,但它不能用于两个不相关的类型进行转换,干说条条没有用,我们看一看它是怎么使用的吧:
int main()
{
double d = 13.14;
int i = static_cast<int>(d);
cout << i << endl;
return 0;
}
怎么理解不能用于两个不相关的类型进行交换呢?
double和int都是同一类型,但是a是一个int类型的变量,而我们却把的强转成(int*)类型当然是不可以了,一个是整形,一个是指针类型,这就叫不相关类型
•reinterpret_cast reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于一种类型转换为另一种不同的类型
typedef void (*FUNC)(); //定义一个指向函数的指针
int DoSomething()
{
cout << "DoSomething" << endl;
return 0;
}
void Test()
{
FUNC f = reinterpret_cast<func> (DoSomething());
}
int main()
{
Test();
return 0;
}
reinterpret_cast可以让编译器一FUNC的定义方式去看待DoSomething函数,但是C++不能保证所有的函数指针都被一样的使用,所以这使用有时会产生不确定的结果
•const_cast const_cast最常用的就是删除变量的const属性,方便赋值
int main()
{
const int i = 10;
int *p = const_cast<int>(&i);
*p = 20;
cout << i << endl;
return 0;
}
为什么要用指针而不是其他类型呢? 我们看看不用指针会出现什么结果: •dynamic_cast dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或者引用(动态转换) 动态转换又分为: 向上转型:子类对象指针->父类对象指针/引用(不需要转换,遵循赋值兼容规则) 向下转型:父类对象指针->子类对象指针/引用(用dynamic_cast转型是安全的) 看看代码实现:
class A
{
public:
virtual void f()
{}
};
class B :public A
{};
void fun(A* pa)
{
B* pb1 = static_cast<b>(pa);
B* pb2 = dynamic_cast<b>(pa);
cout << "pb1:" << pb1 << endl;
cout << "pb2:" << pb2 << endl;
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}
{:--}