Подтвердить что ты не робот

Встроенная виртуальная функция

В С++ я понимаю, что виртуальная функция может быть встроена, но, как правило, намек на inline игнорируется. Кажется, что встроенные виртуальные функции не имеют особого смысла.

Правильно ли это?

Может ли кто-нибудь дать случай, когда встроенная виртуальная функция хороша?

4b9b3361

Ответ 1

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

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

Ответ 2

Чтобы полностью ответить на этот вопрос, нужно понять, что свойство быть virtual применяется независимо от самой функции и вызовов, сделанных для этой функции. Существуют виртуальные и не виртуальные функции. Существуют виртуальные и не виртуальные вызовы этих функций.

То же самое относится к свойству inline. Существуют инелинные и нестрочные функции. И есть встроенные и неинтенсивные вызовы этих функций.

Эти свойства - virtual и inline - при применении к самой функции не конфликтуют. У них просто нет причин и никаких шансов на конфликт. Единственное, что спецификатор inline изменяется для самой функции, состоит в том, что он изменяет правило одной определённой функции для этой функции: функция может быть определена в нескольких единицах перевода (и она должна быть определена в каждой единицы перевода, где она используется), Единственное, что изменит спецификатор virtual, состоит в том, что класс, содержащий эту функцию, становится полиморфным. Это не влияет на саму функцию.

Таким образом, нет абсолютно никаких проблем при объявлении функции virtual и inline одновременно. Нет никаких оснований для конфликта. Это совершенно легально на языке С++.

struct S {
  virtual void foo(); 
};

inline void S::foo() // virtual inline function - OK, whatever
{
}

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

Определяющей особенностью виртуального вызова является то, что он разрешен во время выполнения, что означает, что в целом невозможно встроить истинные виртуальные вызовы:

S *s = new SomeType;
s->foo(); // virtual call, in general case cannot be inlined

Однако, если вызов сам по себе не является виртуальным (даже если он переходит к виртуальной функции), вложение не является проблемой вообще:

S *s = new SomeType;
s->S::foo(); // non-virtual call to a virtual function, can easily be inlined

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

S ss;
ss.foo(); // formally a virtual call, but in practice it can easily be inlined

В некоторых случаях это сложнее, но все же выполнимо:

S *s = new S;
s->foo(); // virtual call, but a clever compiler might be able
          // to figure out that it can be inlined

Ответ 3

У вас могут быть виртуальные функции как встроенные. Решение о вызове функции callline не просто выполняется во время компиляции. Это может быть в любое время между компиляцией и рутимом. Вы можете обратиться к этой статье с Herb Sutter. Inline Redux