6.c++语言级别的类型转换
c++语言级别的类型转换
const_cast:去掉常量属性的一个类型转换
static_cast:提供比编译器认为安全的类型转换
reinterpret_cast:提供C风格的强制类型转换
dynamic_cast:主要在继承结构中,可以支持RTTI类型识别的上下类型转换
const_cast
int main() {
int a = 10;
const int* p = &a;
int *q = const_cast<int*>(p);
// char *q = const_cast<char*>(p); 报错
//double *q = const_cast<double*>(p); 报错
*q = 20;
cout<<a<<" "<<*q<<endl;
return 0;
}
/*
const_cast<type>(express)的type只接受express本身类型的指针后引用
*/
const_cast使用格式:const_cast(expression)
适用场景:用来移除非 const 对象的引用或指针的常量性(const),使用const_cast去除 const 对于引用和指针的限定,通常是为了函数能够接受参数或返回值。注意:目标类型只能是指针或引用,const_cast是对const的一种补充
//const_cast只能作用于指针或引用,去const化
int main()
{
//对于引用
int a = 100;
const int& ra = a; //此时ra的值不可以发生改变
const_cast<int&>(ra) = 300; //对ra进行去const化,ra的值就可以发生改变
cout << ra << " " << a << " ";
//对于指针
const int* p = &a;
*const_cast<int*>(p) = 100;
cout<<a;
}
终端输出: 300 300 100
那么如果对象是const类型的呢?
int main()
{
const int a=100;
const int&ra = a;
const_cast<int&>(ra) = 200;
cout << a << " " << ra << endl;
}
终端输出: 100 200 //这不同于非const对象,但是ra与a的值就不同了,这只改变了ra的值但没有改变a的值
那么再看一个
struct Node
{
int a;
};
int main()
{
const Node st = { 40 };
const Node& pd = st;
const_cast<Node&>(pd).a = 100;
cout << pd.a << " " << st.a;
}
终端输出: 100 100 //很奇怪,这怎么又相等了
结论:const_cast只有对非const变量使用const的指针或引用是安全的,若原生就是const的,再对const_cast后的指针或引用执行写操作是未定义的
static_cast
static_cast
语法格式:static_cast
适用场景:再一个方向上可以作隐式转换,再另一个方向上就可以作静态转换
int main()
{
//双隐
double d;int i;
//d = i;i = d; //两个方向都是被允许的,称为双隐式转换
d = static_cast<double>(i);
i = static_cast<double>(d);
d = static_cast<double>(10/3);
//单隐
void *P;int* p;
//p = q是可以的,q = p不可以,void*类型可以被任意指针类型赋值
q = static_cast<int *>(p);
//再比如malloc函数
q = static_cast<int*>(mallloc(sizeof(10)*10));
}
reinterper_cast
与C语言相同
dynamic_cast
主要用于继承结构,可以支持RTTI类型识别的上下转换
//学好c++还需知道的底层知识
#include <iostream>
using namespace std;
class Base
{
public:
virtual void func() = 0;
};
class Derive1 : public Base
{
public:
void func(){cout<<"Derive1::func()"<<endl;}
int d1;
};
class Derive2 : public Base
{
public:
void func(){cout<<"Derive2::func()"<<endl;}
//实现了新的API接口
void derive2func(){cout<<"derive2func()"<<endl;}
int d2;
};
void func(Base* b)
{
/*
* dynamic_cast会检查指针或引用是否会指向一个Derive2类型
* 通过p -> vfptr -> RTTI 来确定
* 如果确认指向的就是Derive类型没那么就返回一个指向Derive类型的指针
* 否则返回空指针nulllptr
* */
Derive2 *p = dynamic_cast<Derive2*>(b);
if(p == nullptr)
{
b->func();
}
else {
p->derive2func();
cout<<p->d2;
}
}
/*需求:
* 只要是Derive2就调用新的APIderive2func
* 其他的调用func()
*
* 这就要求可以识别传入引用的类型
* */
int main()
{
Derive1 d1;
Derive2 d2;
func(&d1);
func(&d2);
return 0;
}
static_cast是静态类型转换,但dynamic_cast 是动态类型转换可以识别RTTI类型
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?