C++类型转换
C++有可以使用static_cast、dynamic_cast、const_cast、reinterpret_cast来进行类型的转换。现在将每一个的使用方法进行一下总结。
1.static_cast
这个运算符的功能是把一个表达式转换为某种类型,但是没有运行时类型检查来保证转换的安全性。可以用来转换的类型主要如下:
- 类中基类和派生类之间的指针或者引用的转换:向上转换是安全的(派生类的指针转换为基类),但是向下转换的时候由于没有类型检查,所有是不安全的。
- 基本数据类型之间的转换。
- 空指针转换为目标类型的空指针。
- 任何类型的表达式转换为void类型。
static_cast不能把原来表达式中的const、volatile、_unaligned属性转换成没有。请看下面例子
1 char firstChar = 'A'; 2 int firstInt = static_cast<int>(firstChar); 3 const char* constStr = "this is a test string"; 4 char* str = static_cast<char*>(constStr);
上面的第4行代码是不能编译通过的。
2.dynamic_cast
dynamic_cast的转换需要目标类型和源对象有一定的关系:继承关系。换句话说就是dynamic_cast就是用来检查两者是否有继承关系,所有dynamic_cast只能接受类对象的指针或者是引用的类转换。用法表达式如下:
dynamic_cast<type_id>(expession)。type_id只能是类的指针、引用或者是void*。如果type_id是一个指针或者引用,那么expression也必须是指针或者引用,type_id和expression必须对应起来。
dynamic_cast在执行的时候决定真正的类型,如果转换是安全的,dynamic_cast就会传回适当的转换过的指针,如果转换是不安全的,就会返回空指针。
在类层次向上转换的时候,dynamic_cast和static_cast的效果是一样的。
在类层次向下转换的时候,由于dynamic_cast会做类型检查,所有比static_cast更加的安全。如下的例子:

class person { public: int n_num; virtual void doSomething() { cout << "i am a person" << endl; } }; class colorPerson :public person { public: char* mName; }; void change(person *person) { colorPerson * cp1 = static_cast<colorPerson*>(person); cout << "start to call cp1" << endl; if (cp1 != NULL) { cp1->doSomething(); } else { cout << "cp1 is null" << endl; } colorPerson *cp2 = dynamic_cast<colorPerson*>(person); cout << "start to call cp2" << endl; if (cp2!= NULL) { cp2->doSomething(); } else { cout << "cp2 is null" << endl; } } int main() { person *p1=new person(); change(p1); colorPerson *cp1 = new colorPerson(); change(cp1); return 0; }
输出结果是这样的:
在定义person类的时候,我们是定义了一个virtual的dosomething(),这个virtual对应dynamic_cat是必须的,如果没有virtual,就会报编译错误。因为dynamic_cast转换是在运行时进行转换,运行时转换就需要知道类对象的信息(继承关系等)。如何在运行时获取到这个信息——虚函数表。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具