强
制
类
型
转
换
C
⻛
格
的
强
制
类
型
转
换
在
C
语
⾔
中
,
强
制
类
型
转
换
是
通过
“(
⽬
标
类
型
)
变
量
名
”
或
者
是
“
⽬
标
类
型
(
变
量
名
)”
所
实
现
的
。
例
如
int(3.14)
或
者
(int)3.14
(int)3.14
这
样
的
⽅
式
常
称
之为
C
⻛
格
的
类
型
转
换
,
⽽
int(3.14)
则
被
称
之为
函
数
⻛
格
的
强
制
类
型
转
换
。
这
两
种
⽅
式
在
其
它
语
⾔
中也
⽐
较
常
⻅
static_cast
基
本
使
⽤
static_cast<
⽬
标
类
型
>(expression) C++
中
的
提
供
的
类
型
转
换
均
以
类
模
板
的
⽅
式
给
出
static_cast
即
为
静
态
类
型
转
换
,
在
编
译
时
进
⾏
类
型
检
查
以
及
类
型
转
换
,
其
作
⽤
主
要
有
以
下
4
个
⽅
⾯
⽤
途
相
关
类
型
间
的
转
换
最
典
型
的
例
⼦
就
是
整
型
和
实
数
类
型
之
间
的
转
换
,
double -> int
,
int -> double
,
float -> int
等等
double pi = 3.14;
int k = static_cast<int>(pi);
⼦
类
对
象
向
⽗
类
对
象
的
转
换
⼦
类
对
象
向
⽗
类
对
象
相
当
于
对
⼦
类
对
象
进
⾏
了⼀个
“
切
⽚
”
,
只
会
保
留
⽗
类
中
存
在
的
信
息
Base b = static_cast<Base>(derived_ins);
void *
与
其
它
类
型
指
针
之
间
的
转
换
operator new
就
是
使
⽤
static_cast
将
void *
转
换
成
指
向
具
体
对
象
的
指
针
的
void *memory = operator new(sizeof(Buz));
buz = static_cast<Buz *>(memory);
左
值
与
右
值
之
间
的
转
换
std::move()
⽅
法
将
⼀个
左
值
转
换
为
右
值
,
其内
部
就
是
使
⽤
static_cast
所
实
现
的
实
际
上
std::forward
内
部
也
是
使
⽤
static_cast +
引
⽤
折
叠
所
实
现
的
dynamic_cast
基
本
使
⽤
dynamic_cast<
⽬
标
类
型
>(expression)
dynamic_cast
主
要
⽤
于
⽗
类
和
⼦
类
之
间
的
类
型
转
换
,
能
够
将
⽗
类
指
针
或
者
是
引
⽤
安
全
的
转
换
成
派
⽣
类
的
指
针
或
者
引
⽤
,
这
个
过
程
发
⽣
在
运
⾏
时
。
并
且
,
dynamic_cast
正
确
⼯
作
的
前
提
是
⽗
类
中
存
在
⾄
少
⼀个
虚
函
数
也
就
是
说
,
dynamic_cast
主
要
⽤
在
多
态
类类
型
,
有
时
候
我
们
需
要
将
基
类
指
针
特
例
化
,
就
可
以
使
⽤
该
类
模
板
进
⾏
类
型
转
换
转
换
⽬
标
指
针
当
我
们
的
转
换
⽬
标
为
指
针
时
,
也
就
是
⼦
类
指
针
,
若
转
换
失
败
,
则
返
回
空
指
针
(nullptr)
引
⽤
当
我
们
的
转
换
⽬
标
为
引
⽤
时
,
也
就
是
⼦
类
引
⽤
,
若
转
换
失
败
,
则
会
直
接
抛
出
std::bad_cast
异
常
,
因
为
没
有
空
引
⽤
之
说
const_cast
基
本
使
⽤
const_cast<
⽬
标
类
型
>(expression)
const_cast
的
主
要
作
⽤
就
是
添
加
或
去
除
指
针
或
者
是
引
⽤
的
const
属
性
,
但
不
可
以
是
值
类
型
该
类
型
转
换
绝
⼤
部
分出
现
在
函
数
重
载
中
,
其
余
场
合
使
⽤
const_cast
去
除
const
属
性
就
是
⼀个
很
危
险
的
⾏
为
⽰
例
int a = 1024;
const int *ptr = &a;
int *ktr = const_cast<int *>(ptr);
*ktr = 2048;
cout << *ktr << endl;
这
段
代
码
能
够
正
确
的
编
译
和
运
⾏
,
但
是
强
烈
建
议
不
要
这
么
做
,
很
容
易
引
发
系
统
漏
洞
⽤
途
函
数
重
载
⽐
如
说
有
这
样
的
⼀个
函
数
,
接
收
两个
stirng
,
返
回
⻓
度
较
⻓
的
那
个
string &longer_string(string& a, string& b) {
return a.size() > b.size() ? a : b;
}
上⼀
版
的
函
数
有
⼀个
局
限
性
,
⼀
⽅
⾯
是
不
能
接
收
const
类
型
的
实
参
,
另
⼀
⽅
⾯
则
不
能
接
收
右
值
const string &longer_string(const string& a, const string& b) {
return a.size() > b.size() ? a : b;
}
这
样
就
没
问
题
了
,
const
和
⾮
const
字
符
串
都
能
使
⽤
但
是
上
⾯
的
改
进
版
本
也
有
问
题
,
因
为不
管
实
参
是
不
是
带
有
const
属
性
的
,
我
们
的
longer_string
都
将
其
隐
式
地
转
换
成
常
量
引
⽤
了
string &longer_string(string& a, string& b) {
auto &r = longer_string(const_cast<const string&>(a),
const_cast<const string&>(b));
return const_cast<string&>(r);
}
这
样
⼀
来
我
们
就
不
再
需
要
在
longer_string
的
⾮
常
量
引
⽤
的
重
载
函
数
中
重
复
书
写
逻
辑
,
⽽
只
是
进
⾏
⼀些
类
型
转
换
最
后
⼀个
函
数
版
本
我
们
⾸
先
利
⽤
const_cast
为
形
参
添
加
const
属
性
,
得
到
的
结
果
再
去
除
const
属
性
,
⾏
为
安
全
因
此
,
对
于⼀个
⾮
常
量
的
指
针
或
者
引
⽤
来
说
,
我
们
可
以
先
将
其
转
换
成
const
指
针
或
引
⽤
,
然
后
做
⼀些事
情
。
事
情
⼀
做
完
,
再
把
它
们
的
const
属
性
“
撸
掉
”
,
⼤
家
就
当
⽆
事
发
⽣
过
另
外
,
const_cast
只
对
“
底
层
” const
有
⽤
,
也
就
是
const T *
,
对
于
顶
层
const
,
也
就
是
T * const
是
没
有
⽤
的
reinterpret_cast
基
本
使
⽤
reinterpret_cast<
⽬
标
类
型
>(expression)
reinterpret_cast
主
要
⽤
于
处
理
⽆
关
类
型
间
的
转
换
,
也
就
是
说
两个
转
换
类
型
之
间
可
以
没
有
任
何
关
系
,
想
怎
么
转
都
⾏
常
⻅
⽤
途
将
⼀
种
类
型
的
指
针
转
换
成
另
⼀
种
类
型
的
指
针
,
按
照
转
换
后
的
内
容
重
新
解
释
内
存
中
的
内
容
int i = 68;
int *ptr = &i;
char *ktr = reinterpret_cast<char *>(ptr);
cout << *ktr << endl;
这
⾥
我
们
将
int
指
针
转
换
成
了
char
类
型
的
指
针
,
也
就
是
说
,
原
本
ptr
指
针
读
取
4
字
节
的
内
容
,
⽽
ktr
则
只
会
读
取变
量
i
的
第
⼀个
字
节
将
⼀个
整
型
转
换
成
指
针
,
或
者
将
⼀个
指
针
转
换
成
整
型
评论0