Чтобы полностью ответить на этот вопрос, нужно понимать, что свойство быть virtual
независимо от самой функции и вызовов, сделанных к этой функции. Есть виртуальные и не виртуальные функции. Существуют виртуальные и невиртуальные вызовы этих функций.
То же самое и со свойством быть inline
. Есть iniline и non-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
person
AnT
schedule
25.01.2010