Ответ 1

Прежде всего, использование vtables - это реализация, определенная и не обязательная по стандарту.

Для реализаций, использующих vtable, ответ: Да, обычно. Вы можете подумать, что vtable не требуется для абстрактных классов, потому что производный класс будет иметь свой собственный vtable, но он необходим во время построения: при создании базового класса он устанавливает указатель vtable в свою собственную таблицу vtable. Позже, когда вводится конструктор производного класса, вместо этого он будет использовать свою собственную таблицу vtable.

Тем не менее, в некоторых случаях это не требуется, и vtable можно оптимизировать. Например, MS Visual С++ предоставляет флаг __declspec(novtable) для отключения генерации vtable на чистых интерфейсных классах.

Ответ 2

Здесь, похоже, распространенное заблуждение, и я думаю, что следы его источников все еще можно найти в Интернете. Пол Дилашиа написал в 2000 году, что -

... видеть, что компилятор все еще генерирует vtable , все из которых записи NULL и все еще генерирует кода для инициализации vtable в конструктор или деструктор для A.

В действительности это могло быть правдой, но, разумеется, это не так.

Да, у абстрактных классов есть vtables, также с чистыми абстрактными методами (они действительно могут быть реализованы и вызваны), а yes - их конструктор инициализирует чистые записи заданным значением. Для VС++, по крайней мере, это значение находится в адресе функции CRT _ purecall. Фактически вы можете контролировать это значение, либо перегрузка purecall самостоятельно или используя _set_purecall_handler.

Ответ 3

Да. Если вы скажете:

virtual void foo() = 0;

почти буквально назначение 0 для записи в таблице vtable. Не принимайте это слишком буквально, но это хороший способ запомнить, что это значит.

Ответ 4

У нас есть виртуальная таблица для класса, который имеет как минимум одну виртуальную функцию. эта виртуальная функция также может быть чистой. это означает. класс abstact может иметь vtable.

в случае классов abstact запись vtable будет NULL. когда вы пытаетесь создать экземпляр абстрактного класса, он будет проверять таблицу vtable и проверять наличие значения NULL или нет. если присутствует NULL, компилятор выдаст ошибку.