Xin*_*ang 4 c++ pointers visual-studio
我正在读" Inside the C++ Object Model "一书.书中有一个例子:
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
Run Code Online (Sandbox Code Playgroud)
在前面的代码中,地址Derived :: v1&Derived :: v2的打印都是0.但是,如果通过变量打印相同的地址:
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
Run Code Online (Sandbox Code Playgroud)
通过检查&Derived :: 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));
Run Code Online (Sandbox Code Playgroud)
Derived :: v1 的地址为0,但Derived :: v2的地址为4.我不明白为什么&Derived :: v2 在分配给变量时变为4.
检查汇编代码,当直接查询Derived :: v2的地址时,它被转换为0 ; 但是当它分配给变量时,它会被转换为4.
我在VS2008和VS2012上测试过,结果是一样的.所以我认为必须有一些理由让微软选择这样的设计.
而且,如果你喜欢这样:
d1.*(&Derived::v2) = 1;
Run Code Online (Sandbox Code Playgroud)
显然&派生:: v2不是0.为什么编译器会区分这两种情况?
任何人都可以告诉后面发生的事情吗?谢谢!
- 编辑 -
对于那些认为&Derived :: v1没有获得有效地址.你有没有这样做过?
Derived d1, d2;
d1.*p = 1;
d2.*p = 1;
Run Code Online (Sandbox Code Playgroud)
海报问我这个问题,起初我也怀疑有类似的错误原因.这不是VC++特有的.
事实证明,正在发生的事情是,类型&Derived::v2不是int Derived::*,但是int Base2::*,它自然会有零偏移,因为它是相对于Base2的偏移.当您将其显式转换为a时int Derived::*,将更正偏移量.
在VC++或GCC或Clang上尝试这个代码......我正在使用stdio/printf.
struct Base1 { int a; };
struct Base2 { int b; };
struct Derived : Base1, Base2 { };
#include <cassert>
#include <cstdio>
#include <typeinfo>
using namespace std;
int main () {
printf( "%s\n", typeid(&Derived::a).name() ); // mentions Base1
printf( "%s\n", typeid(&Derived::b).name() ); // mentions Base2
int Derived::* pdi = &Derived::b; // OK
int Base2::* p2i = &Derived::b; // OK
//int Base1::* p1i = &Derived::b; // ERROR
assert( sizeof(int*) == sizeof(pdi) );
printf( "%p %p", p2i, pdi ); // prints "(nil) 0x4" using GCC 4.8 at liveworkspace.org
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1882 次 |
| 最近记录: |