BigSpoon 发表于 2016-3-29 11:44:05

关于const_cast问题?

请问,ncref和val的地址一样,使用ncref指针修改值之后为什么val值不变?

muyu0096 发表于 2016-3-30 20:35:24

const_cast<typename> 运算符,只是改变指针的const属性,但const命名的变量依旧不能改变。
换句话说,就是指针不是const指针,const int* 变为int*,但指向的变量val依旧是const。
我觉得是编译器行为,目的是保证只要const的变量,就一定不能改变,至于上面的运算符的作用,往往是用于参数传递。
如有函数   void fun(int n);
如果需要传入的实参是一个const变量,而我们也知道fun函数本身并不会改变参数的值,这个时候,如果把形参声明为非const是无法通过编译的,只有用const_cast<int>,之后,可以代入函数。

反汇编的源码也说明了const值的不可改变,你的程序,用vs2010调试运行时,cout<<val的反汇编代码,
00F942DCpush       0Dh
00F942DEmov         ecx,dword ptr
你看这里压入的是 0Dh,也就是13这个字面变量,
而普通的变量打印的汇编代码则是
00F9428Cpush      eax
00F9428Dmov         ecx,dword ptr
00F94293call      dword ptr
压入的是eax(或别的寄存器),寄存器里存着变量的值,也显示出是一个普通变量。
看的出来,该地址的值虽然被改变了,但val依旧被解释为字面常量,并且在编译过程中已经被替换为13了,也正因为编译时就是13,所以编译器是不允许你改变val的值的,否则就乱套了。

但也有一个很有意思的事情,*(&val)的值虽然为13不变,但*(int*)(&val)的值却为23.这里的强制类型转换,应该彻底抹去了指针和val变量的关系。看汇编代码,也是体现出前者是字面值,而后者是一个变量。
        cout<<"*(&val): "<<*(&val)<<" ;*(int*)(&val): "<<*(int*)(&val)<<endl;        //13 ;23
00F94318mov         esi,esp
00F9431Amov         eax,dword ptr
00F9431Fpush      eax
00F94320mov         edi,esp
00F94322mov         ecx,dword ptr                 //对应源代码 *(int*)(&val)
00F94325push      ecx                                        //压入的是寄存器
00F94326push      offset string " \xa3\xbb*(int*)(&val): " (0F97AFCh)
00F9432Bmov         ebx,esp
00F9432Dpush      0Dh                                        //对应源代码 *(&val),压入的是字面常量0Dh
00F9432Fpush      offset string "*(&val): " (0F97898h)
00F94334mov         edx,dword ptr


在你的程序基础上我增加了若干代码,我觉得基本上说明了const_cast<typename>运算符的这种性质
#include "stdafx.h"
#include<iostream>


using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{       
        const int val=13;
        int temp=15;
        const int* ptr=&temp;
        int* ppp=const_cast<int*>(ptr);
        *ppp=16;
        //        (*ptr)++;    // 接触引用的值依旧是const
        ptr++;                       //说明指针不是常量
        //        (*ptr)++;    //指针+1了,指向下一个地址了,但其解除引用后依旧是const
        ptr--;
               
        ppp=const_cast<int*>(&val);
        (*ppp)=23;
       
        cout<<*ppp<<" ;&ppp: "<<ppp<<endl;
        cout<<val<<";&val: "<<&val<<endl;                        //val=13
        cout<<"*(&val): "<<*(&val)<<" ;*(int*)(&val): "<<*(int*)(&val)<<endl;        //13 ;23

        cin.get();
        return 0;
}

BigSpoon 发表于 2016-3-31 13:40:28

muyu0096 发表于 2016-3-30 20:35
const_cast 运算符,只是改变指针的const属性,但const命名的变量依旧不能改变。
换句话说,就是指针不是c ...

我是使用Qt做的,虽然还是不太理解,但是最终并没有改变const 变量的值。
页: [1]
查看完整版本: 关于const_cast问题?