umesh_tk85 Jun2010 Ответов: 6

Виртуальная функция


Каковы преимущества и недостатки виртуальных функций?

Arun Jacob

Причина моего голосования 1
Попробуйте некоторые интернет-ресурсы/книги.

6 Ответов

Рейтинг:
50

Aescleal

Главным преимуществом виртуальных функций является то, что они непосредственно поддерживают объектно-ориентированное программирование. Когда вы объявляете функцию виртуальной, вы говорите, что именно то, какой код выполняется, зависит от типа объекта, против которого вы его вызываете.

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

void foo( interface_ptr *p )
{
    p->a();
    p->b();
}


вы не можете точно сказать, какой путь кода он будет следовать.

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

Овации,

Пепел


Рейтинг:
2

Arun Jacob

Это очень простой вопрос, лучше вам изучить некоторые основы.

Ключевое слово Virtual позволяет переопределить метод в наследуемом классе.

Виртуальный C#[^]


Рейтинг:
1

Emilio Garavaglia

Виртуальные функции необходимы для поддержки полиморфизма времени выполнения.

class A
{
public:
   virtual ~A() {}
   virtual void hallo()
   { std::cout << "I'm A[" << this << "]" << std::endl; }
};

class B: public A;
{
public:
   virtual void hallo()
   { std::cout << "I'm B[" << this << "]" << std::endl; }
};

int main()
{
    static const size_t N = 4;
    A* v[N];

    for(size_t i=0; i<N; i+=2)
    {
       v[i]   = new A;
       v[i+1] = new B;
    }

    for(size_t i=0; i<N; ++i)
       v[i]->hallo();

    for(size_t i=0; i<N; ++i)
    { delete v[i]; v[i]=0;  }

    return 0;
}


Даже если main управляет только A* (а new B возвращает A B*, который автоматически преобразуется в A*, являющийся производным от A), создание hallo и деструктора virtual делает v[i] (то есть A*) при вызове hallo или при удалении для вызова самого производного метода.

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

Вывод программы должен быть следующим:
I'm A[0xxxxxxx]
I'm B[0yyyyyyy]
I'm A[0zzzzzzz]
I'm B[0wwwwwww]


Рейтинг:
1

Abhinav S

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


Рейтинг:
1

g_shanmuga

виртуальные функции играют важную роль во всех конструкциях фреймворков.


Emilio Garavaglia

Причина моего голосования 2
неуместное уважение к этому вопросу

Aescleal

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

Рейтинг:
0

Shining Legend

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


Emilio Garavaglia

Причина моего голосования 1
Большинство вопросов о пространстве и скорости решаются с помощью оптимизации компилятора.
В 2010 году бояться виртуальных функций просто нет смысла.