- •Полиморфизм
- •Способность объектно-ориентированных языков автоматически определять тип объекта
- •Виртуальные функции имеет смысл использовать только для классов, являющихся базовыми.
- •Правило: указатель на базовый класс может ссылаться на объект этого класса или любого
- •Пример. Использование указателей на классы.
- •int main(){
- •Пример. Использование виртуальных функций.
- •void sound(Animal& i)
- •Переопределим класс Animal:
- •Пример. Использование указателей на объекты. Приведение типов.
- •class Dog: public Animal
- •int main()
- •Механизм работы позднего связывания
- •В каждом классе также помещается указатель VFPTR на таблицу виртуальный функций.
- •При явном связывании мы получаем
- •Для указателей, имеющих тип базового класса, компилятор запрещает вызовы тех виртуальных функций, которые
- •Абстрактные базовые классы
- •Пример. Работа с абстрактным классом
- •Чистые виртуальные функции могут быть определены, но только вне объявления класса.
- •class Dog: public Animal
- •char *eat() {
- •Виртуальные деструкторы class Base1
- •class Base2
- •int main()
- •Чистые виртуальные деструкторы
- •Виртуальные функции в деструкторах
- •int main {
- •Пример. Перегруженные переопределённые функции
- •class Derived2: public Base { public:
- •int main() { char *s;
- •Множественное наследование
- •Вызов конструкторов при создании объекта класса D происходит в том порядке, в котором
- •class A { public:
- •class C: public A, public B { public:
- •Виртуальный базовый класс
- •class A:public virtual W { public:
- •int main() {
- •Виртуальные базовые классы инициализируются перед любыми невиртуальными базовыми классами в том порядке, в
- •Пример. Использование одного класса в качестве виртуального и невиртуального базового класса
Полиморфизм
Полиморфизм (динамическое связывание, позднее связывание) – это свойство ООП,
благодаря которому одно и тоже сообщение может вызывать различные действия на этапе выполнения.
Полиморфизм – это характеристика методов, а не объектов.
Несмотря на то, что полиморфизм реализуется через архитектуру класса, полиморфными могут быть только методы класса, а не весь класс.
В С++ полиморфная функция привязывается к одной из возможных функций только тогда, когда ей передается конкретный объект, т. е. в
С++ вызов функции в исходном коде только обозначается, без точного указания на то,
какая именно функция вызывается.
Этот процесс называется позднее связывание.
При раннем связывании идентификаторы функций ассоциируются с физическими адресами до этапа выполнения, еще на стадии компиляции и компоновки.
Способность объектно-ориентированных языков автоматически определять тип объекта
на этапе выполнения программы называется
RTTI (run-time type identification –
идентификация во время выполнения).
Виртуальные функции
Полифорфизм в ООП реализуется через
механизм виртуальных функций.
Виртуальные функции – это функции, вызов которых зависит от типа объектов.
Виртуальные функции имеет смысл использовать только для классов, являющихся базовыми.
Объявление функции виртуальной для одиночного класса синтаксически корректно, но приведет только к потере времени в момент выполнения.
Виртуальная функция объявляется с помощью ключевого слова virtual.
class A {
…
virtual void f(){} };
Правило: указатель на базовый класс может ссылаться на объект этого класса или любого другого, производного от базового.
Объект базового класса
Указа- |
Объект производного |
класса |
Указа- |
|
тель |
тель |
|||
|
|
|||
на БК |
|
|
на ПК |
|
|
Объект производного |
класса |
|
Пример. Использование указателей на классы.
class A
{
…
};
class B : public A
{
…
};
class C: public B
{
…
};
int main(){
A aobject; B bobject; C cobject; A *pa; B *pb; C *pc; pa=&aobject;
pa=&bobject;
pa=&cobject; //pb=&aobject; Ошибка!!! pb=&bobject; pb=&cobject; //pc=&aobject; Ошибка!!! //pc=&bobject; Ошибка!!! pc=&cobject;
return 0;
}
Пример. Использование виртуальных функций.
class Animal
{
public:
char* speak() {return "Не известно";}
};
class Dog: public Animal
{
public:
char * speak() {return "Гав!!!";}
};
void sound(Animal& i)
{
printf("%s\n",i.speak());
}
int main()
{
Animal a; sound(a);
Dog Sharic; sound(Sharic); return 0;
}
Переопределим класс Animal:
class Animal
{
public:
virtual char* speak() {return "Не известно";}
};
Класс Dog и функции sound() и main() оставляем без изменений.