Я читать эту статью «Virtual method table»виртуальная таблица метод множественного наследования
, например, в указанной выше статье:
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();
В статье, автор вводит, что макет памяти объекта d
заключается в следующем:
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()
Вопрос о d->f2()
. Вызов d->f2()
проходит B2
указателя как this
указателя, поэтому мы должны сделать что-то вроде:
(*(*(d[+8]/*pointer to virtual method table of D (for B2)*/)[0]))(d+8) /* Call d->f2() */
Почему мы должны пройти B2
указатель как this
указателя не оригинальный D
указателя ??? Фактически мы вызываем D :: f2(). Исходя из моего понимания, мы должны передать указатель D
как this
в функцию D :: f2().
___update____
Если пропускание B2
указателя как this
к D :: f2(), что, если мы хотим получить доступ к членам класса B1
в D :: f2() ?? Я считаю, что B2
указатель (это) показано, как это:
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
Он уже имеет определенное смещение адреса начала этого смежного расположения памяти. Например, мы хотим получить доступ к b1
внутри D :: f2(), я предполагаю, что во время выполнения он сделает что-то вроде: *(this+4)
(this
указывает на тот же адрес, что и b2), который будет указывать b2
в B
????
(1) Что вы подразумеваете под «взаимозаменяемым», можете ли вы объяснить немного более подробно? (2) Если передать указатель 'B2' как' this' в D :: f2(), что делать, если мы хотим получить доступ к членам класса B1 в D :: f2()? Для (2), пожалуйста, ознакомьтесь с обновлением вопроса. – Fihop
Большое спасибо! Пожалуйста, подтвердите. 'B2 b2; b2.test() ', это указатель' B2', переданный как 'this' на' B2 :: test() 'определенно, так как' b2' является отдельным объектом. Для 'D d; д.test() ', компилятор передает указатель fixup, который фактически указывает на под-объект' B2' 'D' как' this' to 'test()', поскольку фактически вызывающая функция - 'B2 :: test() '. Если 'this' не указывает на' B2' внутри 'D', это вызовет проблемы при доступе к членам' B2' внутри функции 'B2 :: test()'. Вот почему я думаю, что мы должны передать указатель fixup как 'this'. Этот пример не может объяснить обновление. Спасибо еще – Fihop
Для 'D d; d.test() ', я согласен, мы делаем что-то вроде' d.test (B2 * b2) '(означает, что' this' указывает на под-объект 'B2' of D). Однако внутри 'B2: test',' b2-> f2() 'должно выполняться' D :: f2'. Я прав? Теперь проблема превращается в то, что 'this' передается в' b2-> f2() ' – Fihop