Адрес C ++ указателя на член класса данных в Visual Studio

Я читаю книгуВнутри объектной модели C ++, В книге есть такой пример:

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

В предыдущем коде печать адреса 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

Изучив размер & 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));

Адрес Derived :: v1 будет0, но адрес Derived :: v2 будет4, Я не понимаю, почему & Derived :: v2 стал4 когда назначить его переменной.

Изучите код сборки, когда непосредственно запрашиваете адрес Derived :: v2, он переводится в0; но когда он присваивается переменной, он переводится в4.

Я тестировал его на VS2008 и VS2012, результат одинаковый. Поэтому я думаю, что должна быть какая-то причина, чтобы заставить Microsoft выбрать такой дизайн.

И, если вы делаете так:

d1.*(&Derived::v2) = 1;

По всей видимостиИ Derived :: v2 не является0, Почему компилятор различает эти два случая?

Может кто-нибудь сказать, пожалуйста, что происходит позади? Спасибо!

--Редактировать--

Для тех, кто думает, & Derived :: v1 не получает действительный адрес. Ты никогда не делал это?

Derived d1, d2;
d1.*p = 1;
d2.*p = 1;

Ответы на вопрос(4)

Ваш ответ на вопрос