Я читаю статью Бьярне: «Multiple Inheritance for C++».деталь компилятора этого указателя и виртуальных функций
В разделе 3 на стр. 370 Бьярне сказал, что «компилятор превращает вызов функции-члена в« обычный »вызов функции с« дополнительным »аргументом, этот« дополнительный »аргумент является указателем на объект для который вызывается функцией-членом. "
Рассмотрим простой класс A
:
class A {
int a;
void f(int i);
};
Вызов функции-члена A :: F:
A* pa;
pa->f(2)
преобразуется компилятором в "обычной функции вызова":
f__F1A(pa, 2)
pa передается как указатель. Это легко понять для приведенного выше примера.
Рассмотрим следующий фрагмент кода:
class A {int a; void f(int);};
class B : A {int b; void g(int);};
class C : B {int c; void h(int);};
Вопрос 1:
Вызов функции-члена A :: F:
C* pc = new C;
pc->g(int)
преобразуется компилятором в «обычный вызов функции»:
g__G1C(pc, int) or g__G1B((*B)pc, int)
Является ли этот указатель a * pc или (* B) pc? Другой вопрос: как компилятор знает, где функции-члены?
Приведем пример выше, добавив ключевое слово virtual.
class A {
int a;
virtual void f(int);
virtual void g(int);
virtual void h(int);
};
class B : A {int b; void g(int); };
class C : B {int c; void h(int); };
Класса C объект С выглядит следующим образом:
С:
----------- vtbl:
+0: vptr --------------> -----------
+4: a +0: A::f
+8: b +4: B::g
+12: c +8: C::h
----------- -----------
Вызова виртуальной функции преобразуются в косвенный вызов компилятора. Например,
C* pc;
pc->g(2)
становится чем-то вроде:
(*((*pc)[1]))(pc, 2)
бумага The Бьярне в Толе мне этот вывод.
Вопрос 2:
(1) В VTBL, я считаю, что эти указатели на функции назначены во время выполнения. Как компилятор знает, что второй указатель функции должен указывать на реализацию класса B g? Как его компилятор ?
(2) В приведенном выше примере все члены являются int и мы предполагаем, что компилятор присваивает 4-байтовой памяти для int. Что, если член равен char, компилятор по-прежнему назначает 4 байта памяти для символа? Или просто один байт?
(3) (*((*pc)[1]))(pc, 2)
, этот указатель здесь представляет собой компьютер, почему бы и нет (* B) pc? Есть ли какое-либо правило для передачи этого указателя?
Может ли кто-нибудь помочь мне ответить на эти вопросы? Я очень ценю это. Завтра у меня есть , который действительно относится к этим проблемам. Пожалуйста помоги!!!
Кажется, что это заглянет в Clang/GCC, чтобы получить ответы. – VermillionAzure
Не используйте форматирование цитаты для текста, который не цитируется, – EJP