news 2026/10/29 22:51:44

一文详解C++中的类型转化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文详解C++中的类型转化

1. C语言中的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。

1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败

2. 显式类型转化:需要用户自己处理

举个例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

intmain()

{

doublei = 4.2;

//隐式类型转化

inta = i;

//显示的强制类型转换

intb = (int)i;

int*p=&a;

intd=(int)p;

cout << i << endl;

cout << b << endl;

cout << a << endl;

cout << d << endl;

}

那为什么还要出现C++中的类型转换呢?

因为C语言中的隐式类型转换会带来很多问题:

比如:

1

2

3

4

5

6

7

8

9

intmain()

{

inti = 0;

size_tsize = 5;

while(size >= i)

{

size--;

}

}

size是无符号整型,i是int,在操作符两端的类型就会发生整型提升,导致size永远大于0,造成死循环。所以C++出了一套类型转化的规范写法。

隐式类型转化有些情况下可能会出问题:比如数据精度丢失

显式类型转换将所有情况混合在一起,代码不够清晰

因此C++提出了自己的类型转化风格,注意因为C++要兼容C语言,所以C++中还可以使用C语言的转化风格。

2. C++强制类型转换

static_cast,reinterpret_cast,const_cast,dynamic_cast,这是c++规范的四种类型转化。

1. static_cast

2.reinterpret_cast

3.const_cast

我们来看一个例子:

1

2

3

4

5

6

7

8

9

intmain()

{

constinta = 2;

int* p =const_cast<int*>(&a);//去掉const属性

*p = 5;

cout << a << endl;

cout << *p << endl;

return0;

}

大家可以猜一下结果是什么?

可能有人会想,这不是改变了吗?为什么还是2呢?

原因是:在编译时,因为是const修饰(不会修改),所以就会把a的值放入寄存器中,通过*p来改变的是内存中的a的值,但是a在寄存器中的值没有改变,依旧是2,所以打印时就是2。为了防止这种优化行为的发生,就会在a的前面加:volatile const int a=2;(表明了a的值会改变,不要放在寄存器中),所以每次去取a的值就会到内存中去取。(保持内存可见性)

就因为const_cast会导致这种危险行为的发生,所以C++就会把const_cast这个类型转化单独拿出来,但用的时候很危险!

可以看出,const_cast取消了const属性。

4.dynamic_cast

这种类型转化是专门来针对父类和子类指针之间的相互转化的:

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用 (动态转换)

向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则,天然的一种行为)

向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

注意:

1. dynamic_cast只能用于父类含有虚函数的类

2.dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

如果我们不使用dynamic_cast来进行向下转型(父类转化为子类),那就会发生越界的情况:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

classA

{

public:

virtualvoidf() {}

int_a = 0;

};

classB :publicA

{

public:

int_b = 0;

};

//C语言中的强转

//void Func(A* ptr)

//{

// // 直接转换是不安全的

// B* bptr = (B*)ptr; //父类转子类

// cout << bptr << endl;

//

// bptr->_a++;

// bptr->_b++; //发生越界

//

// cout << bptr->_a << endl;

// cout << bptr->_b << endl;

//}

voidFunc(A* ptr)

{

// C++规范的dynamic_cast是安全的

// 如果ptr是指向父类,则转换失败,返回空

// 如果ptr是指向子类,则转换成功

B* bptr =dynamic_cast<B*>(ptr);

cout << bptr << endl;

if(bptr)

{

bptr->_a++;

bptr->_b++;

cout << bptr->_a << endl;

cout << bptr->_b << endl;

}

}

intmain()

{

A aa;

B bb;

Func(&aa);

Func(&bb);

return0;

}

总结

这就是C++中的四种类型转化,但是强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。 强烈建议:避免使用强制类型转换

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 14:57:26

Arnis:如何用创新工具一键生成逼真的Minecraft城市世界?

Arnis&#xff1a;如何用创新工具一键生成逼真的Minecraft城市世界&#xff1f; 【免费下载链接】arnis Generate any location from the real world in Minecraft with a high level of detail. 项目地址: https://gitcode.com/GitHub_Trending/ar/arnis Arnis是一款革…

作者头像 李华
网站建设 2026/10/26 18:03:53

突破传统:LightX2V如何重新定义视频生成推理

突破传统&#xff1a;LightX2V如何重新定义视频生成推理 【免费下载链接】lightx2v Lightweight Image Video Action Generation Inference Framework 项目地址: https://gitcode.com/GitHub_Trending/li/lightx2v 在2026年的AI技术浪潮中&#xff0c;我们见证了视频生成…

作者头像 李华
网站建设 2026/10/27 2:13:52

Cactbot安全使用指南:如何合规使用FFXIV战斗辅助工具

Cactbot安全使用指南&#xff1a;如何合规使用FFXIV战斗辅助工具 【免费下载链接】cactbot FFXIV TypeScript Raiding Overlay 项目地址: https://gitcode.com/gh_mirrors/ca/cactbot Cactbot是《最终幻想14》&#xff08;FFXIV&#xff09;中备受玩家喜爱的战斗辅助工具…

作者头像 李华
网站建设 2026/10/27 2:13:51

MC68060总线信号深度解析:从硬件通信原理到嵌入式系统设计实践

1. 项目概述&#xff1a;深入MC68060的硬件通信世界 在嵌入式系统和老式工作站的设计与调试中&#xff0c;Motorola&#xff08;后为Freescale&#xff0c;现为NXP&#xff09;的MC68060处理器是一个绕不开的经典。作为68000家族的末代“皇帝”&#xff0c;它代表了复杂指令集&…

作者头像 李华
网站建设 2026/10/27 2:13:50

R3nzSkin国服特供版:5分钟解锁英雄联盟全皮肤免费体验指南

R3nzSkin国服特供版&#xff1a;5分钟解锁英雄联盟全皮肤免费体验指南 【免费下载链接】R3nzSkin-For-China-Server Skin changer for League of Legends (LOL) 项目地址: https://gitcode.com/gh_mirrors/r3/R3nzSkin-For-China-Server 还在为英雄联盟国服皮肤价格昂贵…

作者头像 李华
网站建设 2026/10/30 2:18:23

3步解锁QQ音乐加密文件:macOS用户必备的格式转换终极指南

3步解锁QQ音乐加密文件&#xff1a;macOS用户必备的格式转换终极指南 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xff0c;默…

作者头像 李华