求解const_cast的底层实现原理,为什么对常量指针使用后无法改变常量的值

为什么对一个const int指针使用const_cast,将他的值赋值给一个int,通过这个int指针改变常量的值时,编译器通过, 但是输出常量的时候仍然是原来的值,把int指针通过*解引用输出是改变之后的值

img

const 的机制,就是在编译期间,用一个常量代替了 data。这种方式叫做常量折叠。
常量折叠与编译器的工作原理有关,是编译器的一种编译优化。在编译器进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。

常量折叠只对原生类型起作用,对我们自定义的类型,是不会起作用的。

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7652032
  • 除此之外, 这篇博客: 【C++中的类型转换】C语言类型转换与C++类型转换对比,以及4种C++类型转换详解中的 4. const_cast 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 应用场景是去除只读属性,但有一个前提是内存本身必须是可以修改的。

    #include <iostream>
    using namespace std;
    
    void MyPrintStr1(const char* str) //const char* str,对实参设置只读属性,防止误修改
    {
    	cout << str << endl;
    }
    
    void MyPrintStr2(const char* str)
    {
    	cout << str << endl;
    	//str[0] = 'H'; //需要修改实参的场景,但const只读属性,无法修改内存
    	char* temp = NULL;
    	temp = const_cast<char*>(str);
    	temp[0] = 'H';
    
    	cout << str << endl;
    }
    
    int main()
    {
    	//1.在堆栈上分配内存
    	char str1[] = "how to use const_cast";
    	MyPrintStr2(str1);
    
    	//2.使用常量区字符串(内存的常量区不可修改)
    	const char* pStr = "how to use const_cast";
    	MyPrintStr1(pStr);
    	//MyPrintStr2(pStr);
    	//引发了异常: 写入访问权限冲突。temp 是 0xDD9BF4。
    
    	//3.const 类型的字符串
    	const char str2[] = "how to use const_cast";
    	MyPrintStr2(str2);
    	
    	system("pause");
    	return 0;
    }

    在测试函数中,我们分了三种情况,可以看出第1、3种情况可以正常通过const_cast去除只读属性,从而达到修改内存数据的目的,而第2种情况却出现了异常。这是因为,第1、3种情况虽然对字符串增加了只读属性,但是内存本身是在栈上分配的,而栈内存本身是可以修改的,所以运行成功。而第二种情况是使用了常量区(全局区)的内存,这段内存是不可修改的,所以即使我们使用const_cast去除了字符串的只读属性,也无法正常运行,这是因为内存本身不可修改的原因。所以,在使用const_cast的时候,首先要知道,const属性的变量是在哪分配的内存,该内存本身是否可以修改。