Чисто виртуальные функции
Слово "чисто" – в данном случае используется в контексте "пусто". Иными словами, чисто виртуальная функция - функция пустая. Синтаксис создания её таков: class A { public: //чисто виртуальная функция virtual void v_function()=0; }; Как видите, все отличие только в том, что появилась конструкция «=0», которая называется «чистый спецификатор». Чисто виртуальная функция абсолютно ничего не делает и недоступна для вызовов. Ее назначение – служить основой (если хотите, шаблоном) для замещающих функций в производных классах. Класс, который содержит хотя бы одну чисто виртуальную функцию, называется абстрактным классом. Это связано с тем, что создавать самостоятельные объекты такого класса нельзя. Это всего лишь заготовка для других классов. Механизм абстрактных классов разработан для представления общих понятий, которые в дальнейшем предполагается конкретизировать. Эти общие понятия обычно невозможно использовать непосредственно, но на их основе можно, как на базе, построить производные частные классы, пригодные для описания конкретных объектов. Примечание:Приведем пример. Все животные в своем поведении имеют такие функции, как «есть», «пить», «спать», «издавать звук». Имеет смысл определить базовый класс, в котором сразу объявить все эти функции и сделать их чисто виртуальными. А потом из этого класса выводить классы, описывающие конкретных животных (или виды), со своим специфичным поведением. А базовый класс при этом действительно получается абстрактным. Ведь он не описывает никакое более-менее конкретное животное (даже вид животных). Это может быть и рыба и птица.... По сравнению с обычными классами, абстрактные классы пользуются «ограниченными правами».
Пример. Рассмотрим пример иерархии классов, описывающих неких животных. Для упрощения примера ограничимся в описании каждого животного его кличкой и издаваемым животным звуком. Ну, а основной возможностью программы будет вывод на экран списка кличек животных и представления издаваемых ими звуков.
В качестве базового класса создан абстрактный класс Animal. Он имеет единственный член Title, описывающий кличку животного. В нем есть явно определенный конструктор, который присваивает животному его «имя». И, единственная чисто виртуальная функция speak(), которая описывает, какие звуки издает животное. От этого класса отнаследованны все остальные. Кроме одного. Класс «лев» порожден от класса «кошка» (львы это тоже кошки). Это сделано для демонстрации тонкостей применения виртуальных функций. Но об этом классе немного позже. Во всех производных классах также описана собственная замещающая виртуальная функция speak(), которая печатает на экран, звуки, которые издает конкретное животное. В основном теле программы объявлен массив animals[4] указателей типа Animal*. И сразу же созданы динамические объекты классов и заполнен массив указателей. А в цикле for() по указателю просто вызывается виртуальная функция speak(). Результат работы программы таков:
Теперь обратимся к описанию класса Lion (лев). В нем вместо одной виртуальной функции speak() содержится сразу три. Две из них закомментированы. Если вы закомментируете первую функцию, а раскомментируете вторую, то сможете проверить вариант, когда производится попытка соорудить виртуальную замещающую функцию с другим типом возвращаемого значения. В данном случае вторая (неправильная) функция возвращает тип int вместо типа void, который был у функции speak()в базовом классе. Попробуйте скомпилировать программу и произойдет ошибка на этапе компиляции. Теперь, попробуйте раскомментировать третью функцию, а первые две закомментируйте. Компилятор на сей раз просто выдаст только предупреждение. Это тот самый случай, когда объявляется замещающая виртуальная функция с тем же самым типом возвращаемого значения, но с другим набором параметров. Посмотрим, что получилось:
Лев у нас уже не рычит, а мяукает. Это потому, что работает уже совсем другая функция! То есть, раз в данном классе нет правильно определенной виртуальной функции, то по указателю вызывается виртуальная функция speak() из базового класса. А в нашем случае базовым для класса Lion является класс Cat. Вот лев и замяукал.
©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|