Есть ли у абстрактных классов VTABLE? - PullRequest
10 голосов
/ 07 апреля 2010

Ответы [ 3 ]

16 голосов
/ 07 апреля 2010

Прежде всего, использование vtables определяется реализацией и не предписывается стандартом.

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

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

2 голосов
/ 25 мая 2010

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

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

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

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

0 голосов
/ 07 апреля 2010

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

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

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