Главная » Просмотр файлов » А.В. Столяров - Введение в язык Си++

А.В. Столяров - Введение в язык Си++ (1114949), страница 22

Файл №1114949 А.В. Столяров - Введение в язык Си++ (А.В. Столяров - Введение в язык Си++) 22 страницаА.В. Столяров - Введение в язык Си++ (1114949) страница 222019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 22)

Еслив качестве точки привязки выбрать левую нижнюю вершину квадрата,а длину стороны квадрата обозначить буквой а, то ломаная должна на­чаться в точке привязки (что соответствует вектору (0,0)), пройти черезточки (а, 0), (а, а), (0, а) и вернуться в точку (0, 0); всего, таким образом,ломаная будет содержать пять вершин, причём первая и последняя будутсовпадать, чтобы сделать ломаную замкнутой.Чтобы не приходилось каждый раз для представления квадрата пи­сать шесть строк кода (одну для описания объекта PolygonalChain,остальные для добавления вершин), можно описать класс (мы назовёмего Square), который будет унаследован от PolygonalChain, причём от­личаться будет только конструктором:c la s s Square : pu blic PolygonalChain {p u b lic :Square(double x, double y, double a , in t color): PolygonalChain(x, y, color){AddVertex(0, 0 );AddVertex(0, a ) ;AddVertex(a, a ) ;AddVertex(a, 0 );AddVertex(0, 0 );}Подчеркнём ещё раз, что больше ничего описывать для квадрата не нуж­но, всё остальное сделают методы базового класса.§4.8.

В и р ту ал ьн ы й д естр у к торРанее при обсуждении виртуальных функций на стр. 95 мы отметили,что в классе, имеющем хотя бы одну виртуальную функцию, деструктор101тоже следует сделать (объявить) виртуальным, но не объяснили причиныэтого. Попробуем сделать это сейчас.При активном использовании полиморфизма нередко возникает ситу­ация, когда нужно применить оператор d elete к указателю, имеющемутип «указатель на базовый класс», притом что указывать он может ина объект потомка. В этой ситуации необходимо, естественно, вызватьдеструктор, соответствующий типу уничтожаемого объекта, а не указа­теля.

Так, допустим, мы описали указатель на класс GraphObject:GraphObject * p t r ;Теперь вполне корректным будет такое присваивание:p tr = new Square(27.3, 3 7 .7 , OxffOOOO, 1 0 .0 );В результате этого наш указатель имеет тип «указатель на GraphObject»,но реально указывает на объект класса Square. Если теперь потребуетсяуничтожить этот объект, мы можем без всяких опасений выполнитьd e le te p tr ;Поскольку указатель имеет тип GraphObject*, а деструктор классаGraphObject виртуальный, компилятор произведёт вызов деструкторачерез таблицу виртуальных методов уничтожаемого объекта. В резуль­тате этого будет вызван неявный деструктор для класса Square, кото­рый вызовет деструктор класса PolygonalChain, а тот, в свою очередь,деструктор класса GraphObject.

Если бы мы не объявили деструкторкласса GraphOb j ect как виртуальный, компилятор произвёл бы жесткийвызов деструктора по типу указателя, то есть был бы вызван только де­структор класса GraphObject. Между тем, уничтожаемый объект классаSquare порождает и использует список в динамической памяти (из пятиэлементов), и если деструктор класса PolygonalChain не будет вызван,то эти элементы превратятся в «мусор», то есть будут по-прежнему за­нимать память, не выполняя никакой полезной работы.Объявление деструктора как виртуального практически не приводитк расходу памяти: таблица виртуальных методов увеличивается на одинслот, что составляет несколько лишних байтов на каждый новый класс(не объект!).

С другой стороны, сам факт наличия в классе виртуальныхфункций указывает на то, что при работе с объектами класса будет ак­тивно использоваться полиморфизм. Отметим, что при описании классав большинстве случаев трудно предсказать, будут ли объекты потомковтакого класса уничтожаться оператором d elete , применяемым к указа­телю, имеющему тип «указатель на предка».

Решив, что такое удалениенам не понадобится, мы рискуем в дальнейшем забыть об этом и полу­чить трудную для обнаружения ошибку. В связи с этим считается, что102деструктор любого к л асса, имею щ его хотя бы одну ви ртуаль­ную ф ункцию , следует о бъ явл ять к ак виртуальны й, не зад у ­м ы ваясь о том , понадобится это в програм м е или нет; многиеком пиляторы вы д аю т предупреж дение, если этого не сделать.§ 4.9. Е щ ё о п о л и м о р ф и зм еПриведём ещё один пример использования полиморфизма. Пусть мысоздаём графическую сцену4, состоящую из разных графических объ­ектов — точек, окружностей, многоугольников и, возможно, каких-тодругих элементов, представляемых объектами классов, унаследованныхот GraphObject. При этом на момент написания программы мы не зна­ем, сколько и каких именно объектов будет в сцене; так бывает, еслиописание сцены нужно получить из внешнего источника (например, про­читать из файла), либо если сцена генерируется во время исполненияпрограммы (например, случайным образом, что часто используется вовсевозможных программах-«скринсейверах»).Допустим, в некий момент в программе нам всё же становится извест­но, сколько объектов будет содержать сцена.

Это позволит использоватьдля хранения всей сцены динамически создаваемый массив указателейна объекты потомков GraphObject. Пусть, например, количество объек­тов сцены будет храниться в переменной scene_length, а указатель насам массив мы назовём просто scene:in t scene_length;GraphObject **sc e n e ;Когда переменная scene_lenght тем или иным способом получит зна­чение (например, оно будет прочитано из файла), можно будет завестимассив:scene = new GraphObject*[scene_length] ;Теперь благодаря полиморфизму оказываются корректны, например,следующие присваивания (при условии, конечно, что i не превышаетscene_length):scen e[i] = new P ix e l(1 .2 5 , 15.75, OxffOOOO);// ...scen e[i] = new C ir c le (2 0 .9 , 7 .2 5 , 0x005500, 3 .5 );II .

. .scen e[i] = new Square(5 5 .0 , 3 0 .5 , 0x008080, 1 0 .0 );II . . .4Напомним, что под сценой в компьютерной графике обычно понимается весь на­бор графических объектов, видимых одновременно.103и тому подобные. Таким образом, мы получаем массив указателей типаGraphObject*, каждый из которых на самом деле указывает на некото­рый объект к л а сса-п о то м к а. Обратим внимание на то, что нам можетвовсе никогда больше не потребоваться знать, на объекты какого типауказывают конкретные указатели в нашем массиве. Вне зависимости отконкретных типов, мы вполне можем перемещать объекты по экрану,гасить их и снова отрисовывать, ведь методы ShowQ, HideQ и MoveQдоступны для класса GraphObject, а значит, могут быть вызваны по ука­зателю типа GraphObject* без уточнения типа объекта. Точно таким жеобразом благодаря наличию виртуального деструктора можно уничто­жить все объекты сцены, а потом и саму сцену:f o r (in t i= 0 ; i<scene_length; i++) d elete s c e n e [i];d e le te [] scene;Подобные ситуации часто возникают в более-менее сложных програм­мах.

Поскольку конкретные методы, которые нужно вызывать, стано­вятся известны только во время исполнения программы, такой вид поли­морфизма называется динамическим п ол и м орф и зм ом ; он становит­ся возможным благодаря механизму виртуальных функций и является,в конечном итоге, их предназначением.§4.10. П р о б лем а одинаковы х им ён принаследовании. А втом атическое сокры тиеимёнДопустим, мы описали класс А и от него унаследовали класс В, и приэтом в обоих кл ассах есть поля или методы, названные одним и тем жеидентификатором (например, х).

Вообще-то так писать в большинствеслучаев не надо (кроме случая переопределения виртуальной функции),но если вы всё-таки это написали, полезно будет помнить одно важноеправило языка С и + + : введение поля или м етода с именем х в по­рож дённом классе с к р ы в а е т лю бы е поля или методы базовы хклассов, имею щ ие такое ж е и м я5. Если речь идёт в обоих случаяхоб имени поля или о функциях-методах с одинаковым профилем (т. е.одинаковым количеством и типами параметров), правило сокрытия ока­зывается достаточно очевидным.

Очевидно оно и для случая, когда в5Мы не рассматриваем в нашем пособии множественное наследование, но на вся­кий случай отметим, что если поля или методы с одинаковыми именами появились вдвух базовых классах одного порождённого класса, то в таком порождённом классесокрытию подвергнутся имена из обоих базовых классов.104базовом классе имеется функция с именем х, а в порождённом вводит­ся поле х, или наоборот — ведь для имён полей в С и + + перегрузка непредусмотрена. Например:c la s s А { / / . . .p u b lic :void f ( i n t a , in t b ) ;>;c la s s В : public A {double f ; / / метод f ( i n t , in t) теперь скрыт>;Если теперь создать объект класса В, вызвать метод f мы сходу не смо­жем:В Ъ;b . f (2, 3 );/ / ОШИБКА!!! Метод f скрытОднако «скрыт» не значит «недоступен»; в классе В по-прежнему присут­ствует метод f , унаследованный от класса А, просто его вызов необходимоосуществлять с явным указанием области видимости:b .A ::f ( 2 , 3 );/ / всё в порядкеНаиболее неочевидным проявлением описанного правила становитсято, что появившаяся в порождённом классе функция-метод с тем же име­нем, что и метод базового класса, ск ры вает м етод базового к л асса,д аж е если они разл и чаю тся п роф илем .

Перегрузка функций нас вэтом случае не спасает:c la s s А { / / . . .p u b lic :void f ( i n t a , in t b ) ;>;c la s s В : public A {p u b lic :double f(c o n st char * s t r ) ;>;/ / метод f ( i n t , in t) скрытВ b;double t = b . f("a b ra k a d a b ra "); / / всё в порядкеb . f (2, 3 );/ / ОШИБКА!!!b .A ::f ( 2 , 3 );/ / всё в порядке105§4.11. Т еоретико-м нож ественное описаниен асл ед о ван и яВ с я к а я селёдка — рыба, но невсяк ая рыба — селёдка.А . Н ек р асо в . П р и к л ю ч ен и як а п и т а н а В р у н ге л я .Как уже говорилось, при описании объектно-ориентированного про­граммирования можно использовать различные варианты терминологии.Так, термин «вызов метода объекта» эквивалентен термину «отправкасообщения объекту», просто эти термины относятся к разным терми­нологическим системам: о вызовах методов мы говорим при изучениипрактического применения ООП, тогда как передача сообщения — тер­мин, относящийся к теории ООП и к тем языкам программирования,которые полностью соответствуют этой теории (к таким языкам отно­сится, например, Smalltalk).Класс с теоретической точки зрения представляет собой м н о ж е с т в ообъектов, удовлетворяющих определённым условиям.

В этом смысле по­рождённый (наследуемый, или дочерний) класс представляет собой под­м н о ж е с т в о . Действительно, согласно закону полиморфизма объект по­рождённого класса может быть использован в качестве объекта базо­вого класса, то есть, попросту говоря, является одновременно и объек­том порождённого, и объектом базового класса; в то же время объектбазового класса вовсе не обязан быть объектом класса порождённого.Можно прийти к тем же выводам и иначе. Наследование представляетсобой у то ч н ен и е свойств объекта, или, иначе говоря, переход от обще­го случая к частному.

Характеристики

Тип файла
PDF-файл
Размер
1,67 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6418
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее