Виртуальные методы, тип которых известен во время компиляции - PullRequest
5 голосов
/ 02 июня 2011

Если я сделаю что-то вроде:

Dog dog; //class with virtual methods
Cat cat; //class from same base as Dog

dog.eat(); //call virtual method
cat.eat(); //call virtual method

Тогда eat () будут обычными вызовами методов и не потребуют v-таблицы - правильно?Я могу предположить, что он будет работать идентично не виртуальному методу?

(и да, я знаю, что компилятор обрабатывает виртуальные функции не в стандарте - я хочу знать, что делает большинство компиляторов)

Ответы [ 4 ]

4 голосов
/ 02 июня 2011

Когда вы используете object.member - вы не разыменовываете указатель, поэтому это не влияет на методы virtual.Virtual вступает в силу только тогда, когда у вас есть указатель, который может быть полиморфным, и используется динамическая диспетчеризация.

Например:

Cat cat;
Animal *cat2 = &cat;
cat.eat(); // direct call
//... a lot of other code and function calls that pass cat2 around, to avoid optimization
cat2->eat(); // dynamic dispatch

правка исправлено в комментариях

2 голосов
/ 02 июня 2011

Visual Studio может оптимизировать виртуальный вызов в прямой вызов, если профилирование показывает, что определенный тип используется большую часть времени.

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

См. Оптимизация профиля по профилю в MSDN.

Регулярная «девиртуализация» (то есть, на что ссылаются другие ответы) может быть выполнена без профилирования приложения, и это довольно распространенное явление.

GCC включает эту оптимизацию автоматически, но установлен специальный флаг -fdevirtualize :

Попытка преобразовать вызовы в виртуальные функции в прямые вызовы.Это делается как внутри процедуры, так и внутрипроцедурно как часть косвенного встраивания (-findirect-inlining) и межпроцедурного распространения констант (-fipa-cp).Включено на уровнях -O2, -O3, -Os.

из Параметры оптимизации GCC .

1 голос
/ 02 июня 2011

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

1 голос
/ 02 июня 2011

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

Большинство компиляторов увидят это.

...