指向const常量的指针可以修改常量的值
指向const常量的指针可以修改常量的值
实例
先直接看代码:
int main(int argc, char const* argv[])c
{
const int a = 100;
const int* pa = &a;
int* pa_1 = &a;
//*pa = 3; // 编译不过,指针常量不能通过指针修改值
int* b = const_cast<int*>(pa); // 把const转换掉
*b = 3;
cout << "a: " << a << endl; // 100
cout << "*b: " << *pa << endl; // 3
}
输出结果:
a:100
*pa:3
可以看到,指向a的指针的输出值变为了100,但为什么a的值还是100呢,因为const int x = 100;这种情况,编译器会认为x是一个编译期可计算出结果的常量,那么x就会像宏定义一样,用到x的地方会被编译器替换成100。如果我们将其变为运行时初始化:
int func()
{
return 100;
};
int main(int argc, char const* argv[])
{
const int a = func();
const int* pa = &a;
int* b = const_cast<int*>(pa); // 把const转换掉
*b = 3;
cout << "a: " << a << endl; // 3
cout << "*pa: " << *pa << endl; // 3
}
输出结果:
a:3
*pa:3
在这种情况下,a的输出值也变成了 3 。再尝试一下,通过constexpr的情况:
constexpr int func()
{
return 100;
};
int main(int argc, char const* argv[])
{
constexpr int a = func();
const int* pa = &a;
int* b = const_cast<int*>(pa); // 把const转换掉
*b = 3;
cout << "a: " << a << endl; // 100
cout << "*pa: " << *pa << endl; // 3
}
输出结果:
a:100
*pa:3
可以看到,借由constexpr赋予的常量表达式获得在程序编译阶段计算出结果的能力,a的值重新变成了在编译时初始化。
解决方法
对于这种情况,我们可以通过把局部const变量变成全局const变量。代码如下:
const int a = 100;
int main(int argc, char const* argv[])
{
const int* pa = &a;
int* b = const_cast<int*>(pa); // 把const转换掉
*b = 3;
cout << "a: " << a << endl;
cout << "*pa: " << *pa << endl;
}
这段代码将不会正确运行。其原因是,全局常量的存储位置是数据段的全局/静态区,这个内存区是只读的,而局部常量存放于堆栈中,虽然不能直接修改,但可以通过指针间接修改。