У каждого класса есть таблица виртуальных функций в С++?

У каждого класса есть таблица виртуальных функций в С++?

Я знаю, что виртуальная таблица предназначена для полиморфизма. Класс с виртуальными функциями должен иметь v-таблицу. Но как насчет того, чтобы у класса не было виртуальной функции? Или как насчет того, чтобы класс не имел базового класса?


person Anders Lind    schedule 28.02.2012    source источник
comment
Связано: stackoverflow.com/questions /7453269/ Итак, краткий ответ — нет.   -  person Mysticial    schedule 28.02.2012
comment
В стандарте это не указано.   -  person Martin York    schedule 28.02.2012
comment
@LokiAstari: Нет, но в стандарте указано, какие классы являются полиморфными, и в разумной реализации это будут единственные классы с виртуальной таблицей или эквивалентом.   -  person Mike Seymour    schedule 28.02.2012
comment
@MikeSeymour: Да, я педантичен. Но я пытаюсь сказать, что стандарт не определяет, как полиморфизм влияет на макет класса (если вообще).   -  person Martin York    schedule 28.02.2012
comment
Возможный дубликат Все ли классы имеют Vtable создан для них компилятором?   -  person Bergi    schedule 29.08.2017


Ответы (4)


Спецификация языка C++ не определяет, что такое "vtable" или какие классы в ней нуждаются.

Конкретная реализация C++ в компиляторе часто использует виртуальную таблицу для реализации виртуальных методов. Если у класса нет виртуальных методов (и нет суперклассов с виртуальными методами), компилятор может опустить виртуальную таблицу. Однако имейте в виду, что это чисто решение реализации компилятора, и оно не требуется стандартом.

person Greg Hewgill    schedule 28.02.2012
comment
Уточнение того, как он реализует виртуальный, определяется реализацией, однако правила для стандартных типов макетов довольно строгие, и у компилятора мало свободы. То есть стандартный тип макета не может содержать виртуальную таблицу, это нарушит правила стандартного макета. - person edA-qa mort-ora-y; 28.02.2012
comment
@edA-qamort-ora-y: я не уверен, что это правильно. Очевидно, что вы не можете иметь vptr в качестве первого члена (первый объявленный член должен иметь смещение 0), но это единственная проблема, которую я вижу. - person MSalters; 28.02.2012
comment
Я не верю, что у вас могут быть какие-то специальные данные. Учтите, что допускается memcpy между совместимыми с макетом типами, а также через промежуточный буфер символов. Если бы это дополнительное значение каким-то образом идентифицировало класс, то его копирование через memcpy фактически испортило бы целевой тип, поскольку его специальное значение не соответствовало бы тому, что ожидается от класса. Если бы абсолютно ничего не использовало это значение, все было бы в порядке, но тогда это было бы то же самое, что и безымянный отступ. - person edA-qa mort-ora-y; 28.02.2012
comment
так вы имеете в виду, что есть лучшие способы сделать это? - person jokoon; 02.02.2013

Как нестандартное эмпирическое правило (vtables не диктуются стандартом), которое применимо практически ко всем компиляторам:

Только классы с виртуальными функциями-членами и/или виртуальным деструктором имеют виртуальную таблицу. Другие классы нет. Это соответствует общему правилу C++ "плати за то, что используешь".

Конечно, это накладывает на вас важную ответственность: будет ли ваш класс удален полиморфно? То есть будет ли он использоваться как публичный базовый класс и через него удаляться? Затем сделайте деструктор виртуальным.

person Sebastian Mach    schedule 28.02.2012

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

person Naveen    schedule 28.02.2012

v-table содержит адрес функции. Эта таблица будет содержать адреса всех виртуальных функций, определенных в базовом классе. В зависимости от фактического типа объекта этот адрес изменяется и вызывается точная функция.

Если класс не наследует какой-либо класс с виртуальной функцией, ему не нужно содержать какую-либо v-таблицу. Все вызовы функций будут связаны во время компиляции.

person Rajan    schedule 28.02.2012