我在看书Inside the C++ Object Model。在这本书中有类似的例子:C++指针指向Visual Studio中的类数据成员的地址
struct Base1
{
int v1;
};
struct Base2
{
int v2;
};
class Derived : public Base1, public Base2 {};
printf("&Derived::v1 = %p\n", &Derived::v1); // Print 0 in VS2008/VS2012
printf("&Derived::v2 = %p\n", &Derived::v2); // Print 0 in VS2008/VS2012
在前面的代码,地址的派生打印:: V1 &衍生:: V2都将是。但是,如果通过可变打印相同的地址:
int Derived::*p;
p = &Derived::v1;
printf("p = %p (&Derived::v1)\n", p); // Print 0 in VS2008/VS2012 as before
p = &Derived::v2;
printf("p = %p (&Derived::v2)\n", p); // Print 4 in VS2008/VS2012
通过检查&衍生大小:: v1和P,我都得到4。
// Both are 4
printf("Size of (&Derived::v1) is %d\n", sizeof(&Derived::v1));
printf("Size of p is %d\n", sizeof(p));
衍生:: V1的地址将是,但衍生:: V2的地址将是。我不明白为什么& Derived :: v2变成时,将它分配给一个变量。
检查汇编代码,当直接查询Derived :: v2的地址时,它被转换为;但是当将其分配给变量时,它将被转换为。
我在VS2008 & VS2012上测试过它,结果是一样的。所以我认为必须有一些理由让微软选择这样的设计。
而且,如果你这样做:
d1.*(&Derived::v2) = 1;
显然&衍生:: V2不。为什么编译器会区分这两种情况?
任何人都可以请告诉事情发生在后面?谢谢!
- 编辑 -
对于那些认为&衍生:: V1没有得到一个有效的地址。你没有这样做过吗?
Derived d1, d2;
d1.*p = 1;
d2.*p = 1;
您不打印出指向变量的指针地址吗?我不认为你创建Base1/Base 2的对象。 – ATaylor 2013-03-20 09:40:31
你正在获取_undefined behavior_。指向member_的指针不是一个指针,你不能用'printf'的'%p'格式说明符来显示它。 – 2013-04-01 09:27:19