为什么我能够修改const变量通过类,而不是在纯代码.c++
Why I am able to modify const variable through classes and not in plain code. C++
当我写这段代码时,通过指针修改const变量I的值后,我得到I的值为10,但当我打印*ptr时,我得到110。
const int i = 10;
int *ptr = const_cast<int *>(&i);
*ptr = *ptr + 100;
cout << "i: " << i << "t*ptr: " << *ptr << endl;
我得到输出I: 10和*ptr:110。
在这种情况下,我有一个const变量x作为Base类的成员变量。通过函数show(),我可以修改const变量x的值,即当我打印x和*ptr时,我在两者中都得到了改变的值。
class Base
{
public:
const int x;
Base(int i) : x(i) {}
virtual void show()
{
int *ptr = const_cast<int *>(&x);
int *ptr = const_cast<int *>(&x);
cout << "In Base show:n";
cout << "Address of x : " << &x << endl;
cout << "Address in ptr : " << ptr << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
*ptr = *ptr + 10;
cout << "After modifying " << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
}
};
class Derived : public Base
{
public:
Derived(int i) : Base(i){}
virtual void show()
{
int *ptr = const_cast<int *>(&x);
cout << "In Derived show:n";
cout << "Address of x : " << &x << endl;
cout << "Address in ptr : " << ptr << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
*ptr = *ptr + 10;
cout << "After modifying " << endl;
cout << "value in x : " << x << endl;
cout << "value in ptr : " << *ptr << endl;
}
};
int main()
{
Base bobj(5),*bp;
Derived dobj(20), *dptr;
bp = &bobj;
bp->show();
bp = &dobj;
bp->show();
return 0;
}
The output which I am getting is this
In Base show:
Address of x : 0x7fff82697588
Address in ptr : 0x7fff82697588
value in x : 5
value in ptr : 5
After modifying
value in x : 15
value in ptr : 15
In Derived show:
Address of x : 0x7fff82697578
Address in ptr : 0x7fff82697578
value in x : 20
value in ptr : 20
After modifying
value in x : 30
value in ptr : 30
有人能帮忙吗?
你的代码只是有未定义的行为:你不能修改一个常量对象,你的const_cast
允许你违反这一点(这就是为什么基本上永远不使用const_cast
是一个好主意,只有极少数例外)。因此,询问代码中断的特定方式的原因和方式没有什么意义。但如果你一定要知道,常数积分表达式通常按值直接折叠到它们被引用的地方,就像你的例子中发生的那样。
原因是编译器在编译这一行时将i
的值内联到代码中:
cout << "i: " << i << "t*ptr: " << *ptr << endl;
因为i
是const
变量,编译器通过用10
替换上面行的i
来优化代码。如果我们看看生成的程序集(我使用VS2010):
002314F2 mov ecx,dword ptr [ptr] // ptr is being pushed here (110)
002314F5 mov edx,dword ptr [ecx]
002314F7 push edx
002314F8 push offset string "t*ptr: " (23783Ch)
002314FD mov ebx,esp
002314FF push 0Ah // 0Ah is being pushed here (A is hex for 10)
00231501 push offset string "i: " (237830h)
发生的事情是,你修改了内存中的常量,但生成的程序集实际上并不使用内存地址——它只是输出'10',而不管内存中有什么。
正如Kerrek所说,这是未定义的行为,所以其他编译器可能会做一些完全不同的事情。
一般情况下,除了少数例外,使用const_cast
是一个坏主意。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值