Vc对指向类成员变量的指针的特殊处理 ?
我们都知道一个指向类成员变量的指针的值应该是一个offset(偏移量),在C++标准中,它应该被加上1。原因很简单,为了于零指针区别。举例如下
#include<iostream>
using namespace std;
class obj
{
public:
int i;
};
void main()
{
int obj::*ptr=&obj::i;
int obj::*empty=0;
if (ptr==empty)
cout<<"There is a bug!"<<endl;
else
cout<<"All is right!"<<endl;
}
如上,如果不对ptr指针加1,就会无法区分有效的ptr和指向“空”的empty,所以,这是很符合逻辑的。可是,问题来了,在VC6中我查看了一下ptr的值,它居然是0!码如下:
。。。。。。
print("the value in obj::*ptr is %p\n",ptr);
结果输出为0!(它应该是1的)为什么会这样,看来是VC编译器做了什么动作让事情更符合我们的习惯,可是它到底怎么做到的?
一开始我想到了是不是系统已经对class::*的==运算符重载了,后来否定了这个想法。因为如果是通过重载来实现,不外乎先将指针的值加1在比较,可是,零指针的值也会因此而变得非零,这个方法被枪毙了,此路不同。
后来产生了一个新的想法,ptr中的内容到底是不是0?有可能ptr中的内容根本就是+1,但只要对起进行操作(非比较)编译器自动减1。为了验证这个想法,写了下面的代码
int* adr=reintepret_cast<int*>(p);
cout<<"p is "<<(long)adr<<endl;
结果……,编译错误!我faint,看看msdn对reintepret_cast运算符的解释吧--“The reinterpret_cast operator allows any pointer to be converted into any other pointer type”。呵呵,any ->any ?在这儿就不行!看来,我的猜想很有可能,为什么vc对这种类型的指针保护如此严密,是不是为了掩盖我刚才所说的“黑箱动作”?我无能为力了,哪位高人有兴趣把ptr的值真正取出来让我看看好吗?以解我心头的困惑。