Adresse des C ++ - Zeigers auf das Klassendatenelement in Visual Studio

Ich lese das BuchInnerhalb des C ++ - Objektmodells. In dem Buch gibt es ein Beispiel wie:

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

Im vorherigen Code wird der Ausdruck der Adresse Derived :: v1 & Derived :: v2 beides sein0. Wenn Sie jedoch dieselbe Adresse über eine Variable ausgeben:

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

Durch Untersuchen der Größe von & Derived :: v1 und p erhalte ich 4 in beiden.

// Both are 4
printf("Size of (&Derived::v1) is %d\n", sizeof(&Derived::v1));
printf("Size of p is %d\n", sizeof(p));

Die Adresse von Derived :: v1 lautet0, aber die Adresse von Derived :: v2 lautet4. Ich verstehe nicht, warum & Derived :: v2 wurde4 wenn Sie es einer Variablen zuweisen.

Untersuchen Sie den Assemblycode. Wenn Sie die Adresse von Derived :: v2 direkt abfragen, wird sie in a übersetzt0; aber wenn es einer Variablen zugewiesen wird, wird es in a übersetzt4.

Ich habe es sowohl auf VS2008 als auch auf VS2012 getestet, das Ergebnis ist dasselbe. Ich denke, es muss einen Grund geben, Microsoft zu veranlassen, sich für ein solches Design zu entscheiden.

Und wenn dir das gefällt:

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

Offenbar& Abgeleitet :: v2 ist nicht0. Warum unterscheidet der Compiler diese beiden Fälle?

Kann jemand bitte sagen, was dahinter passiert? Vielen Dank!

--Bearbeiten--

Für diejenigen, die glauben, dass & Derived :: v1 keine gültige Adresse erhält. Hast du das noch nie gemacht?

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

Antworten auf die Frage(4)

Ihre Antwort auf die Frage