Реализация в памяти функций-членов в C ++ - PullRequest
2 голосов
/ 04 июля 2010

Я прочитал статью о виртуальной таблице в Википедии .

class B1
{
public:
  void f0() {}
  virtual void f1() {}
  int int_in_b1;
};

class B2
{
public:
  virtual void f2() {}
  int int_in_b2;
};

used to derive the following class:

class D : public B1, public B2
{
public:
  void d() {}
  void f2() {}  // override B2::f2()
  int int_in_d;
};

После прочтения я не мог не задуматься о том, как не виртуальные функции-члены реализованы в C ++. Есть ли отдельная таблица, такая как v-таблица, в которой хранятся все адреса функций? Если да, как называется эта таблица и что происходит с ней во время наследования?

Если нет, то как компилятор понимает эти утверждения?

D * d1 = new D;
d1->f0();    // statement 1

Как компилятор интерпретирует, что f0 () является функцией B1, и, поскольку D публично унаследовал D, он может обращаться к f0 (). Согласно статье компилятор изменяет утверждение 1 на

(*B1::f0)(d)

Ответы [ 3 ]

7 голосов
/ 04 июля 2010

Не виртуальные функции-члены реализованы как глобальные функции, которые принимают скрытый параметр this.Компилятор знает во время компиляции, какой метод вызывать на основе дерева наследования, поэтому нет необходимости в таблице времени выполнения.

1 голос
/ 04 июля 2010

Существует ли отдельная таблица, такая как v-таблица, в которой хранятся все адреса функций?

Они хранятся в том месте, где они вызваны.

В качестве примера: пока метод f0 не виртуален, компилятор знает, каков его адрес, потому что существует только одна возможность.Пусть адрес будет 0xABCD.Затем код

d1->f0();    // statement 1

компилируется в инструкции:

// push onto the stack 'this' pointer, as you pointed out the address must
// be earlier translated from D class to B1 which is not presented here
push d1

call 0xABCD // call method at known address (jump to this address)
1 голос
/ 04 июля 2010

Помимо этого , я могу только сказать, что обычная функция-член - это просто адрес памяти в классе (я даже считаю, что каждый объект этого класса использует один и тот же "указатель на функцию" в памяти, носо своими переменными).V-таблица - это форма перенаправления во время выполнения, так как компилятор не может знать, с каким объектом точно он имеет дело (очевидно, из-за полиморфизма).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...