c++ виртуальные - встроенная виртуальная функция




функции пример (4)

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

Это правильно?

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


Answers

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

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


Вы можете иметь виртуальные функции как встроенные. Решение сделать встроенный вызов функции принимается не только во время компиляции. Это может быть в любое время между компиляцией и rutime. Вы можете обратиться к этой статье от Херб Саттер. Встроенный Redux


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

То же самое относится и к свойству быть inline . Есть встроенные и не встроенные функции. И есть встроенные и не встроенные вызовы этих функций.

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

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

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

Глядя на форму

Возьмите гусак в форме красной части банки / бутылки. Обратите внимание на то, как консервная банка слегка сужается на самом верху, а этикетка бутылки - прямо. Вы можете различать эти два, сравнивая ширину красной части по ее длине.

Глядя на основные моменты

Одним из способов отличить бутылки и банки - это материал. Бутылка изготовлена ​​из пластика, тогда как банда изготовлена ​​из алюминиевого металла. В достаточно хорошо освещенных ситуациях просмотр зеркальности будет одним из способов сказать этикетку с этикеткой на этикетке.

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







c++