Endereço do ponteiro C ++ para membro de dados de classe no Visual Studio
Estou lendo o livroDentro do modelo de objeto C ++. No livro há um exemplo como:
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
No código anterior, a impressão do endereço Derived :: v1 & Derived :: v2 será ambas0. No entanto, se imprimir o mesmo endereço através de uma variável:
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
Examinando o tamanho de & Derived :: v1 e p, obtenho 4 em ambos.
// Both are 4
printf("Size of (&Derived::v1) is %d\n", sizeof(&Derived::v1));
printf("Size of p is %d\n", sizeof(p));
O endereço de Derived :: v1 será0, mas o endereço de Derived :: v2 será4. Eu não entendo porque o & Derived :: v2 se tornou4 quando atribuí-lo a uma variável.
Examine o código assembly, quando consultar diretamente o endereço de Derived :: v2, ele é convertido em um0; mas quando atribuí-lo a uma variável, ele é traduzido para um4.
Eu testei em VS2008 e VS2012, o resultado é o mesmo. Então, acho que deve haver algum motivo para a Microsoft escolher esse design.
E se você fizer assim:
d1.*(&Derived::v2) = 1;
Pelo visto& Derivado :: v2 não é0. Por que o compilador distingue esses dois casos?
Alguém pode por favor dizer que a coisa acontece por trás? Obrigado!
--Editar--
Para aqueles que pensam, o & Derived :: v1 não recebe um endereço válido. Você nunca fez isso?
Derived d1, d2;
d1.*p = 1;
d2.*p = 1;