C++_强制类型转换

本文详细介绍了C++中的四种强制类型转换:static_cast, const_cast, reinterpret_cast以及旧式强制类型转换。static_cast用于明确且安全的类型转换,const_cast用于改变对象的底层const属性,reinterpret_cast则用于底层位模式的解释,而旧式转换在某些情况下与命名转换等价,但不推荐使用。文章强调了安全使用强制类型转换的重要性。" 116057634,10553855,MATLAB求解六元一次方程组错误解析与解决,"['MATLAB编程', '数学求解', '方程组', '软件错误']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cast-name<type>(expression);

cast-name : static_cast 、dynamic_cast 、 const_cast 、 reinterpret_cast。
dynamic_cast 支持运行时的类型识别。

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
当需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用。
对于编译器无法自动执行的类型转换也非常有用。例如:

  • 我们可以使用static_cast找回存在于void *指针中的值:
void * p = &d;  //任何非常量对象都能存入void*
double *dp =static_cast<double*> (p); //必须确保转换后所得类型就是指针所指类型,不然,未定义。

const_cast

用于改变运算对象的底层const。
const_cast转换符是用来移除变量的const或volatile限定符。

const char *cp;
char * p=const_cast<char*> (cp); //正确,但通过cp写值是未定义行为

传统转换方式实现const_cast。const_cast实现原因就在于C++对于指针的转换是任意的,它不会检查类型,任何指针之间都可以进行互相转换,因此const_cast就可以直接使用显示转换(int*)来代替:

const int constant =21;
const int * const_p=& constant;
int *modifier=(int *)(const_p);

或者可以写作:

const int constant =21;
int *modifier =(int*)(&constant);

但是, 上面只改变了const_p所指向内容的值,不能改变constant的值,虽然它们指向了同一个地址。
实际上,通过改变*modifier的值来改变cons值是未定义的行为,我们需要尽量避免未定义行为的出现。
那么问题来了,既然不想修改const变量的值,为什么要去const呢?
原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数确是const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。

#include<iostream>
using namespace std;
void printer(int *val, string seperator ="\n")
{
   cout<<val<<seperator;
}
int main(void)
{
   const int constant =20;
   printer(const_cast<int *>(&constant));
   return 0;
}

出现这种情况的原因,可能是我们所调用的方法是别人写的。
还有一种我能想到的原因,是出现在const对象想调用自身的非const方法的时候,因为在类定义中,const也可以作为函数重载的一个标识符。
实际上,const_cast常用于有函数重载的上下文中1

reinterpret_cast

reinterpret_cast通常为运算对象的位模式提供较低层次上的解释。

int *ic;
char *pc =reinterpret_cast<char *>(ip);

必须时刻牢记pc所指向的真实对象是一个int而不是字符,如果把pc当成普通的字符指针就可能在运行时发生错误。

string str(pc); //导致异常

使用reinterpret_cast是非常危险的,其本质上依赖于机器,想要安全地使用它,必须对涉及的类型和编译器实现转换的过程非常了解。

要避免强制类型的转换。

旧式的强制类型转换

type(expr);
(type)expr;

根据涉及的类型不同,旧式的强制类型转换分别具有与const_cast 、static_cast、 reinterpret_cast相似的行为。
当我们在某处执行旧式的强制类型转换,如果换成const_cast 、static_cast也合法,则其行为与对应的命名转换一致。如果替换后不合法,则其执行与 reinterpret_cast类似的功能:

char *pc =(char *)ip; //ip是指向整数的指针

与 reinterpret_cast一样。



  1. const_cast与函数重载:
    const string &shorterString (const string &s1,const string &s2) { return s1.size()<s2.size() ? s1:s2;}这个函数的参数和返回类型都是const string的引用,如果对两个非常量实参调用这个函数是可行的,但其返回值仍是const string的引用。
    因此,我们需要一个新的shorterString函数,当他的实参不是常量时,得到的结果是一个普通的引用,使用const_cast:
    string &shorterString (string &s1, string &s2) { auto &r = shorterString (const_cast <const string &>(s1) ,const_cast <const string&>(s2)) ; return const_cast <string&> (r); } ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值