C C++最全c++:四大类型转换_c++cast四种转换,【C C++面试题】

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

}

cin.get();
return 0;

}


输出结果:



> 
> 基类指针转换派生类指针成功  
>  void Derived::show()  
>  基类指针转换派生类指针失败
> 
> 
> 


       第一种情况,先让基类的指针指向派生类对象,这是一种“向上转换”(upcasting),可以直接隐式转换,合乎语法。然后令基类指针“升级为”派生类指针,原则上,这是一种“向下转换”(downcasting),需要显示强制转换,但指向的内存是派生类的,**派生类指针指向派生类的内存**,**理论上不存在安全隐患**,所以用dynamic\_cast进行强转,没任何问题。  
   第二种情况,令派生类指针指向基类对象,显然是存在安全隐患,dynamic\_cast会返回一个null指针,告诉开发者转换失败了。但这个操作发生在运行时。  
   dynamic\_cast和传统的(type)(expression)强制转换的最大区别在于**提供了运行时的类型检查,保证了类型安全,使用强制转换,会跳过编译器的类型检查,但可能会造成运行时异常,导致程序直接崩溃**


### static\_cast:



//与dynamic_cast作用类似,将expression转换为type类型,区别在于,static发生于编译时,dynamic发生于运行时。
static_cast(expression);


       ① 用于类层次结构中基类和派生类之间指针或引用的转换,其中——向上转换是安全的,向下转换是不安全的,但两者均可以通过编译,也就是说开发者要负责强转的运行时安全性,这一点,不如dynamic\_cast安全;



#include
using namespace std;

class Another {};
class Base {};
class Derived :public Base {};

int main() {
// 通过编译,且是安全的
Base*base = static_cast<Base*>(new Derived);
// 通过编译,但是存在安全隐患
Derived*d = static_cast<Derived*>(new Base);
// 没有任何关系的两个类,无法转换,static_cast执行编译时类型检查
Another*a = static_cast<Base*>(new Base);
return 0;
}


       ② 可以用于内置类型的转换。  
   C语言与自己的内置类型隐式转换规则的,比如说,算术运算,低类型自动往高类型转换(如图),但转换的精度损失由开发者负责,编译器往往会提出警告。使用了static\_cast运算符之后,等于告诉编译器,“我知道这里发生了类型转换,我会为转换的安全性负责,你不用管了”,编译器不会发出编译警告,除非你类型转换完全非法(比如 int a = static\_cast(“Hello world!”); ),static\_cast才会报编译错误;



![](https://img-blog.csdnimg.cn/20190625163501335.png)

       ③ 把void\*转换成目标类型的指针;  
   ④ 把任意类型转换成void类型;  
   ⑤ static\_cast无法转换expression的const/volitale/\_\_unaligned属性(会报编译时错误)。


### const\_cast:



//弥补了static_cast无法转换const/volitale的不足,将expression的const/volitale属性移除,仅限于底层const属性.
const_cast(expression);


       ① **顶层const**:表示指针变量是const的,比如`int *const pointer`; **底层const:** 表示指针所指向的变量是const的,比如`const int *pointer`;。理解记忆:所谓底层const就是指我这个变量“底子”就是const,改不了,天生丽质难自弃。反之,则是顶层const。  
   ② `const_cast`不能执行其他任何类型转换,只能用于同类型之间不同`const/ volitale`属性的移除。否则会报编译时错误。  
   ③ **需要注意的是,const\_cast通常对指针和引用进行转换,而无法直接移除内置类型的`const/volitale`属性**,换言之,这种语法直接提供了一个具有写权限的指针或引用,可以通过间接访问的方式,修改常量。


举个例子:



#include
using namespace std;

int main() {

const int a = 10;
const int\*pointer_const = &a;
int\*b = const\_cast<int\*>(pointer_const);
\*b = 20;
cout << "b = " << \*b << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "&a = " << &a << endl;
// a = 50; // 指向a的指针b可以修改a,但是a自身不能修改,因为a是常量

return 0;

}


测试结果:



![](https://img-blog.csdnimg.cn/20190625164253252.png)
        通过`const\_cast` 常量a被修改。但是这里有个有趣的现象,就是,指向a的 指针b被修改了,但是a本身却还是没变,从地址上看,指针b确实指向了常量a,但是\*b和a却不一样,\*\*这是为什么呢?\*\*   推测可能是编译器(这里用的Visual Studio 2017)对字面型常量的引用,有自己的优化,所以a的值没有发生更改,但实际上已经改了,比如换种方式—— 

#include
using namespace std;

int main() {
cout<<“请输入一个数:”<<endl;
int input;
cin>>input;
const int a = input;
const int*pointer_const = &a;
int*b = const_cast<int*>(pointer_const);
*b = 20;
cout << "b = " << *b << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "&a = " << &a << endl;

return 0;

}


实验结果:



![](https://img-blog.csdnimg.cn/20190625164424218.png)

这时会发现,常量a也能改变了(但仍然无法使用a = 30这样的赋值语句来改变a)。


### reinterpret\_cast:



//reinterpret_cast 允许将任何指针转换为任何其他指针类型。 也允许将任何整数类型转换为任何指针类型以及反向转换。
reinterpret_cast(expression);


       ① `reinterpret_cast` 运算符可用于 char\* 到 int\* 或 One\_class\* 到 Unrelated\_class\* 之类的转换,这本身并不安全,但可以通过编译;  
   ② `reinterpret_cast` 的本质作用是重新定义内存数据的解释方式,而不进行任何二进制转换。


### 总结



![img](https://img-blog.csdnimg.cn/img_convert/455b0dba3eda596c8fab70e7c2de7c56.png)
![img](https://img-blog.csdnimg.cn/img_convert/5950752196a4dc1c925fa90b11cffe28.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值