const指针强转为非const指针后的赋值问题

#include <iostream>

using namespace std;

int main()
{
    const int a = 5;
    const int * p = &a;
    int *p_var = NULL;
    
    p_var = const_cast <int*>(p);   //强转为非const指针
    cout << a <<endl;
    *p_var = 10;    //重新赋值
    cout << "*p=" << *p << endl;         //输出10
    cout << "*p_var=" << *p_var << endl; //输出10
    cout << "a=" << a << endl;           //输出5
    system("pause");

    return 0;
}

以上代码将const int*强转为int*之后再赋值

为什么a的值没有变还是5

而*p 与 *p_var都是10

我没有办法理解啊,望高手指点

 

以上代码是在VC6上的运行结果

wangyao1052的主页 wangyao1052  |  初学一级  | 园豆: 128
提问于:2011-09-25 10:28
最佳答案
1

const_cast用来丢弃变量的const声明,但不能改变变量所指向的对象的const属性。即:const_cast用于原本非const的对象;如果用于原本const的对象,结果不可预知(C++语言未对此种情况进行规定)

清注意我上面用下划线标示的“变量”vs“对象”

这个要自己慢慢体会

一般情况下const_cast是用于这种情形:const指针(变量)指向非const对象,程序员确认这一点(所指向的对象非const)时,使用const_cast操作符丢弃变量的const修饰获得一个非const指针

看看《The C++ Programming language(special edition)》第15.4.2.1节的最后一段,仔细揣摩它的每个词。。。

收获园豆: 80
回复  |  bye_passer  |  菜鸟二级  |园豆:367  | 2011-09-25 15:09
其他回答(1)
0

这个 其实 很简单,你p是const指针,指向的那块内存区域的值是不可改变的,现在将p赋给p_var,p_var是非const指针,也就是说p_var指向的那块内存区域的值是可改变的,a是个常量,其值肯定是不会变的。如果没有const_cast编译是不能通过的,那先看看const_cast到底做了什么

const_cast<T*>(a)
编译器在编译期处理
去掉类型中的常量,除了const或不稳定的变址数,T和a必须是相同的类型。
表达式const_cast<T*>(a)被用于从一个类中去除以下这些属性:const, volatile, 和 __unaligned。
class A { ... };
void f()
{
    const A *pa = new A;//const对象
    A *pb;//非const对象
    //pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
    pb = const_cast<A*>(pa); // 现在OK了
    ...
}
对于本身定义时为const的类型,即使你去掉const性,在你操作这片内容时候也要小心,只能r不能w操作,否则还是会出错
const char* p = "123"; 
char* c = const_cast<char*>(p); 
c[0] = 1;   //表面上通过编译去掉了const性,但是操作其地址时系统依然不允许这么做。
const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。

现在应该明白了吧。强制转换把p的const属性去掉了,又因为p和p_var又指向新的同一块内存区域,就是文字常量10所在的内存区域,所以*p和*p_var的值都是10.
尽量不要使用const_cast,如果发现调用自己的函数,竟然使用了const_cast,那就赶紧打住,重新考虑一下设计吧。

回复  |  Daywei  | 园豆:549  (小虾三级)  | 2011-09-25 14:42  |

你的解释应该是错的

楼下的解释是对的

const_cast用于原本非const的对象;如果用于原本const的对象,结果不可预知(C++语言未对此种情况进行规定)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值