Введение в программирование

       

Виртуальные методы


Виртуальные методы объявляются в базовом классе с ключевым словом virtual, а в производном классе могут быть переопределены. Прототипы виртуальных методов как в базовом, так и в производном классе должны быть одинаковы.

Применение виртуальных методов позволяет реализовывать механизм позднего связывания, при котором определение вызываемого метода происходит на этапе выполнения, а не на этапе компиляции. При этом вызываемый виртуальный метод зависит от типа объекта, для которого он вызывается. При раннем связывании, используемом для не виртуальных методов, определение вызываемого метода происходит на этапе компиляции.

На этапе компиляции строится таблица виртуальных методов, а конкретный адрес проставляется уже на этапе выполнения.

При вызове метода с использованием указателя на класс действуют следующие правила:

  • для виртуального метода вызывается метод, соответствующий типу объекта, на который указывает указатель.
  • для не виртуального метода вызывается метод, соответствующий типу самого указателя.

В следующем примере иллюстрируется вызов виртуальных методов:

class A // Объявление базового класса { public: virtual void VirtMetod1(); // Виртуальный метод void Metod2(); // Не виртуальный метод }; void A::VirtMetod() { cout << "Вызван A::VirtMetod1\n";}

void A::Metod2() { cout << "Вызван A::Metod2\n"; }

class B : public A // Объявление производного класса {public: void VirtMetod1(); // Виртуальный метод void Metod2(); // Не виртуальный метод }; void B::VirtMetod1() { cout << "B::VirtMetod1\n";} void B::Metod2() { cout << "B::Metod2\n"; } void main() { B aB; // Объект класса B B *pB = &aB; // Указатель на объект класса B A *pA = &aB; // Указатель на объект класса A pA->VirtMetod1(); // Вызов метода VirtMetod класса B pB->VirtMetod1(); // Вызов метода VirtMetod класса B pA->Metod2(); // Вызов метода Metod2 класса A pB->Metod2(); // Вызов метода Metod2 класса B }

Пример 12.1. Вызов виртуальных методов

Результатом выполнения этой программы будут следующие строки:

Вызван B::VirtMetod1 Вызван B::VirtMetod1 Вызван A::Metod2 Вызван B::Metod2

Чисто виртуальной функцией называется виртуальная функция, указанная с инициализатором

=0.

Например:

virtual void F1( int) =0;

Объявление класса может содержать виртуальный деструктор, используемый для удаления объекта определенного типа. Однако виртуального конструктора в языке С++ не существует. Некоторой альтернативой, позволяющей создавать объекты заданного типа, могут служить виртуальные методы, в которых выполняется вызов конструктора для создания объекта данного класса.

Например:

class A{ public: A(); A (const A&); virtual A* virt_object1 () { return new A(); } virtual A* virt_object2 () { return new A(*this); } }



Содержание раздела