我来说说第一个问题吧。
为什么非const成员函数能访问const常量对象?
首先根据LZ给出的一段代码,
const int elem = 10;
int *pt = &elem;
这段代码真的不可以吗?
我们是不是可以换一种思路呢?不过要考虑编译器对于const int elem的实现了。
比如我们看看这段代码。
程序代码:
#include <iostream>
int main()
{
const int a = 20;
std::cout << a << std::endl;
system("pause");
return 0;
}
编译后产生了什么呢?
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
注意push 0x14,const int a = 20;,a没有被保存在堆栈里面,而是直接作为立即数传参了。所以楼主给出的那段通过指针修改const变量是不能运行的。
这只是我的一个随便说法,当然如此说来也是有点牵强。
进行Patch之后呢?
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
嗯……上面我想说明什么?我也不知道我想说明什么。
我只是想阐明一个我认为的道理。既然玩的语言支持Native Code编译,不是基于虚拟机执行的。我只以ASM为标准,从来不会理编译器的规定的。
我们再脑洞打开进行一次作死修改a的值的尝试如何?
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
程序代码:
#include <iostream>
#include <windows.h>
int main()
{
DWORD dwFlag;
BYTE bCode[2] = {0x6A, 0xC}; //push 0xC
PBYTE p = PBYTE(&main);
const int a = 0xC; //十进制的12
VirtualProtect(p, 100, PAGE_EXECUTE_READWRITE, &dwFlag);
while (memcmp(bCode, p, 2))
p++;
p++;
__asm
{
mov eax,p
mov byte ptr[eax],0x50
}
std::cout << a << std::endl;
system("pause");
return 0;
}
(VC6编译器)
回到本源吧。const限定符,我的理解是不允许修改,没有不允许读取。嗯,总而言之,就是这么一句话。前面写的我也不知道自己在说什么。。。。哇咔咔咔,各位拍砖轻点。
const成员函数,只是表明自己不修改,没有规定不读取。
至于LZ的理解,我个人觉得没必要这么复杂化。学了汇编以后就不会按照这个思路去思考了。