在C++中更改const变量的值

Nar*_*a N 16 c++ const

我试图更改一个变量的值,该变量定义为int const,如下所示.

const int w = 10;
int* wp = const_cast <int*> (&w);
*wp = 20;
Run Code Online (Sandbox Code Playgroud)

w的值没有改变,即使在赋值之后仍然是10,尽管它表明w和wp都指向同一个内存位置.但是我可以更改w的值,如果在声明时定义如下

int i = 10;
const int w = i;
Run Code Online (Sandbox Code Playgroud)

如果我改变i的声明使其成为常量

const int i = 10;
Run Code Online (Sandbox Code Playgroud)

w的值不会改变.

在第一种情况下,为什么w的值没有改变,即使w和wp指向相同的内存位置[这是我打印地址时的印象]

与编译器有什么不同,它以不同的方式处理这两种情况?

有没有办法确保w不会失去常数,无论它的定义方式如何?

rmn*_*rmn 15

这是const cast未定义的情况之一,因为代码可能已经过优化,因此w实际上不是变量,并且在编译的代码中并不存在.

请尝试以下方法:

const volatile int w = 10; 
int &wr = const_cast <int &> (w); 
wr = 20; 
std::cout << w << std::endl;
Run Code Online (Sandbox Code Playgroud)

无论如何,我不建议那样滥用const_cast.

  • 神奇的区别是`volatile`关键字.把它拿出去,w = 10,就像Narendra最初的基于指针的例子一样. (3认同)

dor*_*ron 8

上例中的代码转换为以下汇编程序:

    movl    $10, 28(%esp)  //const int i = 10; 
    leal    28(%esp), %eax //int* wp = const_cast <int*>(&i);
    movl    %eax, 24(%esp) //store the pointer on the stack
    movl    24(%esp), %eax //place the value of wp in eax
    movl    $20, (%eax) //*wp  = 20; -  so all good until here
    movl    $10, 4(%esp) //place constant value 10 onto the the stack for use in printf
    movl    $.LC0, (%esp) // load string
    call    printf //call printf
Run Code Online (Sandbox Code Playgroud)

因为原始int i被声明为常量,所以编译器保留使用文字值而不是存储在堆栈上的值的权利.这意味着该值不会被更改,并且您仍然坚持原始10.

故事的寓意是编译时常量应该保持不变,因为这是你告诉编译器的.故事的寓意是,为了改变常数而抛弃常数会导致坏事.


Dav*_*ave 5

const_cast不会消除定义的变量的常量.如果你要在路过参考非const变量取像一个const引用的方法void foo(const int& x),那么你可以使用const_cast修改的值x之内foo,但前提是你实际上是在传递的变量在第一个地方是不是const的.