ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 11) онлайн
Доступ к обычным методам через указатели
Наш первый пример покажет, что бывает, когда базовый и производные классы
содержат функции с одним и тем же именем, и к ним обращаются с помощью
указателей, но без использования виртуальных функций.
Листинг 11.1. Программа NOTVIRT
// notvirt.cpp
// Доступ к обычным функциям через указатели
#include <iostream>
using namespace std;
///////////////////////////////////////////////
class Base //Базовый класс
{
public:
void show() //Обычная функция
{ cout << "Base\n"; }
};
//////////////////////////////////////////////
class Derv1 : public Base //Производный класс 1
{
public:
Листинг 11.1 (продолжение)
void show()
{ cout << "Derv1\n"; }
};
//////////////////////////////////////////////
class Derv2 : public Base //Производный класс 2
{
public:
void show()
{ cout << "Derv2\n"; }
};
//////////////////////////////////////////////
int main()
{
Derv1 dv1; //Объект производного класса 1
Derv2 dv2; //Объект производного класса 2
Base* ptr; //Указатель на базовый класс
ptr = &dv1; //Адрес dv1 занести в указатель
ptr->show(); //Выполнить show()
ptr = &dv2; //Адрес dv2 занести в указатель
ptr->show(); //Выполнить show()
return 0;
}
Итак, классы Dervl и Derv2 являются наследниками класса Base. В каждом из
этих трех классов имеется метод show(). В main() мы создаем объекты классов
Dervl и Derv2, а также указатель на класс Base. Затем адрес объекта порожденно-
го класса мы заносим в указатель базового класса:
ptr = &dv1; //Адрес объекта порожденного класса заносим в //указатель базового
Но постойте, а компилятор на нас не обидится за то, что мы присваиваем ад-
рес объекта одного типа указателю на другой тип? Оказывается, наоборот —
компилятор будет просто счастлив, потому что проверка типов отдыхает в этой
ситуации. Мы скоро поймем, почему. Дело в том, что указатели на объекты порож-
денных классов совместимы по типу с указателями на объекты базового класса.
Теперь хорошо бы понять, какая же, собственно, функция выполняется в этой
строчке:
ptr->show();
Это функция Base::show() или Dervl::show()? Опять же, в последних двух
строчках программы NOTVIRT мы присвоили указателю адрес объекта, при-
надлежащего классу Derv2, и снова выполнили
ptr->show();
Так какая же из функций show() реально вызывается? Результат выполнения
программы дает простой ответ:
Base
Base
Как видите, всегда выполняется метод базового класса. Компилятор не смот-
рит на содержимое указателя ptr, а выбирает тот метод, который удовлетворяет
типу указателя, как показано на рис. 11.1.
Да, иногда именно это нам и нужно, но таким образом не решить поставлен-
ную в начале этой темы проблему доступа к объектам разных классов с помо-
щью одного выражения.

Рис. 11.1. Доступ через указатель без использования виртуальных функций
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
Схожі підручники
- Реферат на тему « Особливості та недоліки оподаткування операцій з недержавного пенсійного забезпечення в Україні »
- РЕГІОНАЛЬНА ЕКОНОМІКА (частина 2)
- Р. ЛАФОРЕ ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть13) онлайн
- Фінансовий Ринок остовні питання
- Товарознавство харчових продуктів функціонального призначення. Навчальний посібник (частина 1)
- ЦЕНТРАЛЬНІ БАНКИ В СИСТЕМІ МОНЕТАРНОГО ТА БАНКІВСЬКОГО УПРАВЛІННЯ
