BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #19244同步于 2009/2/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

求助!const_cast

buptpostman
2009/2/15镜像同步9 回复
const int a = 3; int * p = const_cast<int*> (&a); *p = 6; cout<<(*p==a)<<endl<<(&a==p)<<endl; 为何输出结果是0和1 , 大牛解释下。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
buptmouse机器人#1 · 2009/2/15
【 在 buptpostman (打铁帮帮主之乔帮主) 的大作中提到: 】 : 标 题: 求助!const_cast : 发信站: 北邮人论坛 (Sun Feb 15 14:51:44 2009), 站内 : : const int a = 3; : int * p = const_cast<int*> (&a); : *p = 6; : cout<<(*p==a)<<endl<<(&a==p)<<endl; 碰见过类似的问题; 我是这样子想的,我觉得编译器会在编译阶段就对cosnt int a做了一个替换,类似于c里面的#define,所以 int *p=const_cast(int*)(&a); -> int *p=const_cast(int*)(&3); a的地址是在这里分配的. 同理 cout<<(*p==a)... -> cout<<(*p==3)... : 为何输出结果是0和1 , 大牛解释下。 : -- : 你是飘过窗的雨 : 却停驻我心里 : 因为最初所以永远 : 而散落水中的梦 : 是我执着的心 : 因为短暂而美丽 : :
buptpostman机器人#2 · 2009/2/15
恩 有点明白了 谢谢!
buptpostman机器人#3 · 2009/2/15
看看msdn 上面对const_cast有这样的描述 The const_cast operator can be used to remove the const, volatile, and __unaligned attribute(s) from a class. 这样的话,对于基本类型就无法修改,但对于用class关键字定义的类声明常量, 就可以通过const_cast来修改。 【 在 buptpostman 的大作中提到: 】 : const int a = 3; : int * p = const_cast<int*> (&a); : *p = 6; : ...................
bobten2005机器人#4 · 2009/2/21
我觉得你只说对了一半,个人觉得 const int a = 3; int * p = const_cast<int*> (&a); *p = 6; cout<<(*p==a)<<endl<<(&a==p)<<endl; 中只有单独出现a的地方会被替换成3,而对a取地址不会被替换成3, 否则的话会变成 int * p = const_cast<int*> (&3); 3是一个文字常量,而文字常量是 不可以取址的,这只是我个人的理解,欢迎交流 【 在 buptmouse 的大作中提到: 】 : 碰见过类似的问题; : 我是这样子想的,我觉得编译器会在编译阶段就对cosnt int a做了一个替换,类似于c里面的#define,所以 : int *p=const_cast(int*)(&a); : ...................
bobten2005机器人#5 · 2009/2/21
这个和是不是类没有关系,这里的class是一个宽泛的概念,不仅仅值面向对象里的类类型 【 在 buptpostman 的大作中提到: 】 : 看看msdn 上面对const_cast有这样的描述 : The const_cast operator can be used to remove the const, : volatile, and __unaligned attribute(s) from a class. : ...................
buptmouse机器人#6 · 2009/2/21
【 在 bobten2005 (碧海蓝天) 的大作中提到: 】 : 标 题: Re: 求助!const_cast : 发信站: 北邮人论坛 (Sat Feb 21 19:07:16 2009), 站内 : : 我觉得你只说对了一半,个人觉得 : const int a = 3; : int * p = const_cast<int*> (&a); : *p = 6; : cout<<(*p==a)<<endl<<(&a==p)<<endl; : 中只有单独出现a的地方会被替换成3,而对a取地址不会被替换成3, : 否则的话会变成 int * p = const_cast<int*> (&3); 3是一个文字常量,而文字常量是 : 不可以取址的,这只是我个人的理解,欢迎交流 ~~~~~~~~~~~~~~~~~~~~~ 不是的, c中的#define 是不分配存储空间只是做替换 c++ 中的const是可以分配也可以不分配,一般编译器都是不分配的,在需要的时候再分配一个临时存储空间, 例子中就是在const_cast转换的时候分配的。 : 【 在 buptmouse 的大作中提到: 】 : : 碰见过类似的问题; : : 我是这样子想的,我觉得编译器会在编译阶段就对cosnt int a做了一个替换,类似于c里面的#define,所以 : : int *p=const_cast(int*)(&a); : : ................... : : -- : : ※ 来源:·北邮人论坛 http://forum.byr.edu.cn·[FROM: 59.64.179.*]
bobten2005机器人#7 · 2009/2/22
你说的替换是在所有出现a的地方都会替换吧,那这样的话 int * p = const_cast<int*> (&a)在编译时会变成int * p = const_cast<int*> (&3), 这时怎么把3关联到a呢? 【 在 buptmouse 的大作中提到: 】 : ~~~~~~~~~~~~~~~~~~~~~ : 不是的, : c中的#define 是不分配存储空间只是做替换 : ...................
zieckey机器人#8 · 2009/2/22
基本类型(built-in)也可以修改的 【 在 buptpostman 的大作中提到: 】 : 看看msdn 上面对const_cast有这样的描述 : The const_cast operator can be used to remove the const, : volatile, and __unaligned attribute(s) from a class. : ...................
zieckey机器人#9 · 2009/2/22
针对这个问题,我写了下面的小测试程序: #include <iostream> using namespace std; int main() { const int a = 3; int * p = const_cast<int*> (&a); *p = 6; cout<<"(*p==a):"<<(*p==a)<<",\t"<<"(&a==p):"<<(&a==p)<<endl; cout<<"a="<<a<<",\t*p="<<*p<<",\t(&a)="<<&a<<",\tp="<<p<<endl; cout<<"*(&a)="<<*(&a)<<",\t(int)*(char*)(&a)="<<(int)*(char*)(&a)<<",\t"<<"*p="<<*p<<endl; return 0; } 输出: (*p==a):0, (&a==p):1 a=3, *p=6, (&a)=0xbf94fab4, p=0xbf94fab4 *(&a)=3, (int)*(char*)(&a)=6, *p=6 由此,可以知道一下几点: 1、const的变量是要在内存中分配内存空间的 2、在编译阶段做了文本替换 3、即使是“*(&a)”这样的语句也被编译器直接优化为“a”了,然后直接进行文本替换 所以lz的问题就很好解释了。。。 几点额外的说明: 1) const int SIZE = 100; //标准const变量声明加初始化,因为默认为内部连接所以必须被初始化,其作用域为此文件,编译器对SIZE进行类型检查后直接用在编译时就决定了SIZE的值,并且进行了文本替换 2) 大家看看下面程序,也许有更多的收获: int main() { const int r=100; int a = 0; int * ptr = const_cast<int*>(&r); //C++标准 int * ptr1 = (int*)&r; //C方式 *ptr = 200; a = r; //在编译期间a的值就确定了,所以应该始终等于100 cout<<"r ="<<r<<endl; cout<<"a ="<<a<<endl; cout<<"*ptr ="<<*ptr<<endl; cout<<"*(int*)(&r) ="<<*(int*)(&r)<<endl;//运行期间才决定,所以应该能够反映出来被更改过 *ptr1 = 300; a = r; //在编译期间a的值就确定了,所以应该始终等于100 cout<<"r ="<<r<<endl; cout<<"a ="<<a<<endl; cout<<"*ptr1 ="<<*ptr1<<endl; cout<<"*(int*)(&r) ="<<*(int*)(&r)<<endl;//运行期间才决定,所以应该能够反映出来被更改过 cout<<"&r ="<<(int*)&r<<endl; cout<<"ptr ="<<ptr<<endl; cout<<"ptr1 ="<<ptr1<<endl; return 0; } 输出: r =100 <==注意 a =100 *ptr =200 *(int*)(&r) =200 r =100 a =100 *ptr1 =300 *(int*)(&r) =300 &r =0013FF60 ptr =0013FF60 ptr1 =0013FF60 PS:测试环境为gcc version 4.1.2 20070502 (Red Hat 4.1.2-12) 【 在 buptpostman 的大作中提到: 】 : const int a = 3; : int * p = const_cast<int*> (&a); : *p = 6; : ...................