C++_转换运算符_const_cast

const_cast作用:

作用:去除变量的const或volatile属性

说明,由于不了解volatile,这里不讲关于volatile的知识。

const_cast的用途:

用途:有时候需要把常量的值赋值给普通变量。

const char* max(const char* s1,const char* s2)
{
	return strcmp(s1,s2) > 0 ? s1 : s2;
}

char* p = max("AAA","BBB");//错误

说明:由于防止函数max修改字符串s1 和 s2的内容,就在形参中加入const。在函数返回值时,由于指针p为非const指针,是不允许接受const值的。这就要求取出返回值的const限制,为p赋值。

const_cast的语法:

const_cast<type_id> (expression)

说明:

(1) type_id 和 expression的类型是一样的

(2)  type_id 和 expression应该是引用或指针。

举例:

const int constNum = 0;
int& Num = const_cast<int&>(constNum);
int* pNum = const_cast<int*>(&constNum);

编译器处理方式:

先举个例子:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
	const int constNum = 0;
	int& Num = const_cast<int&>(constNum);

	cout<<"两个变量的地址:"<<endl;
	cout<<"&constNum = "<<&constNum<<endl;
	cout<<"&Num = "<<&Num<<endl<<endl;

	cout<<"原来的值:"<<endl;
	cout<<"constNum = "<<constNum<<endl;
	cout<<"Num = "<<Num<<endl<<endl;


	Num = 10;
	cout<<"现在的值:"<<endl;
	cout<<"constNum = "<<constNum<<endl;
	cout<<"Num = "<<Num<<endl;

	system("pause");
}

输出:


问题:在执行 const_cast 转换后,发现 变量Num 的地址和constNum的地址是一样的,但对Num赋值后,也就是对这个地址赋值后,为什么输出的Num的值和constNum的值为什么不同,Num的值为新值,而ConstNum的值仍然是老值?

分析:这是属于常数折叠或者常量替换

(1)这是由于编译器一般不会为 const常量或者表达式分配内存空间的,而是在编译阶段求出常量表达式的值或者直接把常量的值放入一个符号表中,当const常量或常量表达式在程序中使用时,编译器会在编译阶段把该const常量替换为具体值,和C中的宏define类似。所以在执行cout<<constNum时,constNum的值一直从符号表中取出,而且在预编译后变成了cout<<10。

(2)如果我们在程序中取了这个const常量的地址,那么编译器将为此常量分配一个内存空间,生成一个常量副本, 此时所有通过地址对常量的操作都是针对该副本的。 

所以,&constNum 的地址是一个编译器为其分配的临时空间,其中Num也指向这个临时空间,在执行 Num = 10 后,临时空间的值为10。

注意:

给出一个不需要使用 const_cast的例子:

const int constNum = 0;
int Num = constNum; //num = 0

这里,Num只是引用常量 constNum 中的值,除此之外,变量num和变量constNum 是两个没有半毛钱关系的变量。只有当使用引用或指针指向常量变量时才需要使用const_cast转换,因为在这两种情况才导致Num和常量constNum指向同一个空间,而可能修改constNum中的值。

总结一句,常量是不能改的,想改就找个副本给你改。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
reinterpret_cast是C++中的一种类型转换运算符,用于在不同类型之间进行强制转换。它可以将一个指针类型转换为另一个指针类型,或者将一个整数类型转换为指针类型。这种转换是非常危险的,因为它会绕过编译器对类型的检查,并且可能导致未定义行为。因此,在使用reinterpret_cast时需要非常小心并确保转换是安全和合法的。 举个例子,引用中的代码演示了reinterpret_cast的使用。在这个例子中,将一个char指针转换为float指针,然后打印出float指针所指向的值。由于char和float的内存布局不同,这种转换可能会导致错误的结果,因此需要谨慎使用reinterpret_cast。 另外,引用中的代码演示了使用const_cast将常量对象的const属性去除的过程。在这个例子中,将一个const int对象的指针转换为int指针,并修改所指向的值。需要注意的是,修改常量对象的值是一种未定义行为,因此使用const_cast需要慎重考虑。 总之,reinterpret_cast是一种强制类型转换运算符,可以在不同类型之间进行转换,但需要谨慎使用,并确保转换是安全和合法的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++ static_cast、dynamic_cast、const_cast和reinterpret_cast(四种类型转换运算符)](https://blog.csdn.net/ccc369639963/article/details/122905438)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值