【C++】:常量转换(const_cast)重新解释转换(reinterpret_cast)

396 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

1️⃣前言

之前的笔记写了C++类型转换运算符的前两个static_castdynamic_cast,这使得我们可以根据自身目的来选择合适的运算符,进行类型转换。

  • 今天的笔记内容为常量转换const_cast和重新解释转换reinterpret_cast

2️⃣常量转换(const_cast)

✨用法

常量转换的应用场景为:修改类型的const属性。注意,常量转换的对象只能是指针或引用,即无法支持基本数据类型的转换。因此,使用该const_cast运算可以返回一个指向非常量的指针(或引用),通过该指针(或引用)可以对其数据成员进行任意改变。

总结如下:

  1. 常量指针被转化成非常量的指针,并且仍然指向原来的对象;
  2. 常量引用被转换成非常量的引用,并且仍然指向原来的对象;
  3. const_cast一般用于修改底指针。如const char *p形式

✔️语法

const_cast <要转换的类型>(变量名或表达式)

🌳例子

#include <iostream>
using namespace std;

int main()
{
	// 可以将常量指针转换为非常量指针
	const int* p = 0;
	int* new_p = const_cast<int*>(p);
	
	// 可以将非常量指针转换为常量指针
	int* pp = 0;
	const int* new_pp = const_cast<const int*>(pp);
	 
	/*
	//不能直接对非指针和非引用的变量使用const_cast操作符
	const int data = 0;
	int new_data = const_cast<int>(data); //这是错误的 
	*/
	
	return 0;

3️⃣重新解释转换(reinterpret_cast)

✨用法

运算符reinterpret_cast是一种强制类型转换符,主要用于将变量从这一种数据类型转换为另一种数据类型(甚至可以将一个整数转换为一个指针)。因此,这也是一种最不安全的转换机制,最有可能出现问题。

✔️语法

reinterpret_cast<要转换的类型>(变量名或表达式)

🌳例子

#include <iostream>
using namespace std;

int main()
{
	// 16进制表示
	int num = 0x00636261;
	// 用int类型指针指向num 
	int* p_int = &num;
	// 将int类型的指针转换为char类型的指针 	
	char* p_char = reinterpret_cast<char *>(p_int);
	
	// 输出结果 
	cout<<"p_int的值:" << p_int <<endl;
	cout<<"p_char的值: "<< static_cast<void *>(p_char)<<endl;// 为了输出p_char的值而进行类型转换(不然会输出其指向的字符串) 
	cout<<"p_int指向的内容: " << hex  <<*p_int<<endl;
	cout<<"p_char指向的内容: "<< p_char <<endl;
	
	return 0;
}

运行结果如下:

image.png

分析如下:

  • 可以看到,p_intp_char的值是相同的
  • 原因是:“reinterpret_cast运算符并不会改变括号中运算对象的值,而是对该对象从位模式上进行重新解释
  • 也就是说,当我们使用reinterpret_cast运算符p_intint*转变成char*类型并用于初始化p_char后,并不会改变p_int的值。
  • 注意,此时p_char指针也指向了num的内存空间,当我们输出p_intp_char指向的内容时发现,结果不一样。
  • p_int输出的是数值636261p_char输出的是字符串abc
  • 原因在于指针读写规则不同
  • 我们知道,不同数据类型的指针需要放置地址的内存是同样大的。而这些不同类型的指针差异性在于其寻址出来的对象类型不同。也就是说,指针类型教导了编译器如何解释某个特定地址中的内存内容及其大小。
  • 因此,上述代码中,输出结果不同的原因在于,p_int指针是int*类型的,输出其内容时结果为数值636261,而p_char指针是char*类型的,通过p_char读写num内存区域时,将不再按照int型变量的规则,而是按照char型变量规则.
  • 还有一点,最后输出char*指针时,输出流会把它当做输出一个字符串来处理,直至遇到'\0'才表示字符串结束。因此p_char输出的是字符串abc0x61是字符'a'的ASCII码,以此类推)

内容示意图如下:

image.png