tabela de método virtual para herança múltipla
Estou lendo este artigo "Tabela de método virtual"
Exemplo no artigo acima:
class B1 {
public:
void f0() {}
virtual void f1() {}
int int_in_b1;
};
class B2 {
public:
virtual void f2() {}
int int_in_b2;
};
class D : public B1, public B2 {
public:
void d() {}
void f2() {} // override B2::f2()
int int_in_d;
};
B2 *b2 = new B2();
D *d = new D();
No artigo, o autor introduz que o layout da memória do objetod
é como isso:
d:
D* d--> +0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
B2* b2--> +8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d
Total size: 20 Bytes.
virtual method table of D (for B1):
+0: B1::f1() // B1::f1() is not overridden
virtual method table of D (for B2):
+0: D::f2() // B2::f2() is overridden by D::f2()
A questão é sobred->f2()
. A chamada parad->f2()
passa umB2
ponteiro como umthis
ponteiro, então temos que fazer algo como:
(*(*(d[+8]/*pointer to virtual method table of D (for B2)*/)[0]))(d+8) /* Call d->f2() */
Por que devemos passar umB2
ponteiro como othis
ponteiro não o originalD
ponteiro ??? Na verdade, estamos chamando D :: f2 (). Com base no meu entendimento, devemos passar umaD
ponteiro comothis
para a função D :: f2 ().
___atualizar____
Se passar umB2
ponteiro comothis
para D :: f2 (), e se quisermos acessar os membros deB1
classe em D :: f2 () ?? Eu acredito noB2
ponteiro (isto) é mostrado assim:
d:
D* d--> +0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
B2* b2--> +8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d
Ele já possui um certo deslocamento do endereço inicial desse layout de memória contíguo. Por exemplo, queremos acessarb1
dentro de D :: f2 (), acho que em tempo de execução, ele fará algo como:*(this+4)
(this
aponta para o mesmo endereço que b2), o que indicab2
noB
????