Главная » Просмотр файлов » Бьерн Страуструп. Язык программирования С++. Специальное издание (2011)

Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 105

Файл №1004033 Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (Бьерн Страуструп. Язык программирования С++. Специальное издание (2011)) 105 страницаБьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033) страница 1052018-10-07СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Переменная типа «указатель на член класса Х» объявляется с применением декларатора вила Х:: *. Часто применяют оператор гурек(е1'для улучшения читаемости неудобоваримого синтаксиса деклараторов языка С. Обратите внимание на то, что синтаксис декларатора Х:: * в точности соответствует обычному декларатору * для указателей.

Указатель т на некоторый член класса можно применять как с указателем на объект, так и с самим объектом, для чего нужно использовать операции ->* и . ', соответственно. Например, выражение р->*гп связывает пг с объектом, на который указывает р, а выражение оЬ|. *т — связывает гп с объектом оЬ|. Результат этих операций используется в соответствии с типом»п. Невозможно сохранить результат операций ->* и . * для его дальнейшего использования. Конечно же, если бы мы заранее знали, какой именно член класса нам нужен, то мы могли бы работать с ним напрямую, а не затевать всю эту катавасию с указателями на члены классов. Как и в случае обычных указателей на функции, мы применяем указатели на функции-члены классов тогда, когда нам нужно сослаться на функцию-член, имя которой неизвестно. В отличие, однако, от обычных указателей на переменные или функции, которые представляют собой готовые целевые адреса в памяти, указатели на члены классов скорее являются смешениями в рамках некоторых структур (или индексами массивов).

Когда указатель на член класса комбинируется с указателем на объект класса соответствующего типа, тогда-то и вырабатывается точный адрес конкретного члена для этого конкретного объекта. Графически это можно изобразить следующим образом: Так как указатель на виртуальную функцию-член класса (з в нашем примере) является в некотором смысле смещением, то он не зависит от точного расположения объекта в памяти. Поэтому указатель на виртуальную функцию-член можно безопасно передавать из одного адресного пространства в другое адресное пространство, при условии одинаковой раскладки объекта в них обоих.

В то же время, указатели на невиртуальные функции-члены (как и обычные указатели на функции) нельзя передавать в другие адресные пространства. Очевидно, что функции, вызываемые через указатели на функции-члены, могут быть виртуальными. Например, когда мы вызываем зизреиИ() через указатель на функцию-член, вызывается правильная версия функции, соответствующая объекту, к которому применялся указатель на функцию-член. Это является важным аспектом поведения указателей на функции-члены классов.

Интерпретируюший код может использовать указатели на функции-члены для вызова функций-членов, представленных в строковом вице: 508 Глава 15. Иерархии классов тир<в!ггпя, Я!й !пгебгасе > оаг!аЫег тор<за(пя, РзЫ тет> орегайоп; юЫ саИ тетЬег (з!г(пх заг, з!г!пе орег) ( (ганаЫе! гаг) ->*орега!1оп (орег) ) (); ) // лог. орег() Чрезвычайно полезное применение указателей на функции-члены рассматривается в связи со стандартным шаблоном тегп!)зп () в 83.8.5 и 818.4. Так как статический член класса не ассоциируется с конкретным объектом класса, то указатель на статический член похож на обычный указатель.

Например: с1азз Таей //... таис когй зсьейи!е ( ); )' го!й ('р) () = ьТазл::зслейи1ег // о)г юЫ (Талл:: 'рт) () = ЬТазй::зслейи!е; //еггою обычный указатель присваивается //указателю на функцию-член класса Указатели на классовые поля данных рассматриваются в 8С.12.

15.5.1. Базовые и производные классы Производный класс в любом случае содержит члены, достающиеся ему от базовых классов. Кроме того, часто у него есть и собственные члены. Из этого следует, что мы можем безопасно присваивать значения указателей на члены базовых классов указателям на члены производных классов, но не наоборот. Например: с1ат !ехз: риЫ(с Ягй 1п!егТасе ( риЬВс: коЫ Фас! ( ) уоЫ зизрепй (); // ... Ыггиа1 ю1й рпт(); рейка!е: пес!ог ю гогй (51й (пзефасе:: *рт1) () = ь!ехг::рг(пз; ю1й (игл!:: *рт!) () = ьу!й 1пгег)асе::з1аго // еггог // о/с Это правило кажется противоположным известному правилу, что можно присваивать значения указателей на производные классы указателям на базовые классы.

Однако оба правила действуют абсолютно согласованно: они гарантируют, что указатели никогда не адресуют объекты, у которых отсутствуют свойства, подразумеваемые типом указателя. В нашем примере указатели типа Ягй 1п!еггасе::" могут использоваться с любыми объектами иерархии Я!й 1пгег)асе, часть из которых не относится к типу !ех!. Следовательно, у них может не быть функции-члена гех~::ргтг(), 509 ( 5.6. Свободная память которым мы пытались проинициализировать рпп'.

Отказывая в инициализации, ком- пилятор предотвращает ошибки времени выполнения. 15.6. Свободная память Можно управлять выделением памяти для класса, определив в нем функции орегагог пеп () и орегагог е!е1еге () (96.2.6.2). Однако замена глобальных функций орегагог пем() и орегагог Ие1еге() — занятие не для слабонервных. В конце концов, другие программисты могут рассчитывать на предопределенное поведение механизма работы с динамической памятью, или представить свои собственные версии. Более ограниченный и более надежный подход состоит в реализации этих операций в рамках конкретного класса. Причем этот класс может быть и базовым для многих других классов.

Например, для класса Етр1оуее из 9) 2.2.6 можно было бы определить специализированные операции выделения и освобождения памяти: с(азз Етр1оуее ( У.. риЫ1с: У ... ю!й* орегагог пет (пге П; юЫ орегагог йе1еге (коЫ", з(хе г); )) Функции-члены орега(ог пеп () и орегагог Ие(еге () неявно статические, так что у них отсутствует возможность работы с указателем гй1з и они не изменяют объекты. Они просто предоставляют память, которую конструктор может инициализировать, а деструктор — очищать (деинициализировать): коЫ* Етр(оуее:: орега<ог пет (згсе г з) ( У выделить з баит памяти и вернуть указатель на эту память юЫ Етр!оуее:: орегагог ае(еге ( юЫ* р, з(хе г з) ( (у'(р) ( жудаием только ески р/=О, зее зб.2.б, Зб.2.б.2 ~7 полагаем, что р указывает на з байт памяти, выделенной при помои(и Ю Етр(оуеекорега(ог пев() и освобождаем эту память для повторного использования ) Использование загадочного до сих пор аргумента типа з(хе г теперь становится понятным — это размер фактически уничтожаемого объекта.

Если, например, удаляется объект типа Етр!оуее, то этот аргумент равен зпеоу(Етр(оуее), а если удаляется объект типа Мапааег — то з1геоу(Мапаяег) . Это позволяет специфическому для класса аллокатору не хранить объем выделенной памяти для каждого объекта. Но, естественно, он может и хранить эту информацию (аллокаторы общего назначения Глава 15. Иерархии классов с1ат Мапааег: риа!1с Етр!оуее ( (п! 1еге1; уу ... )' гощу' ( ) ( Етр1оуее* р = пет Мапалег; ае1езе р; УУ беда: потерян истинный тип В этом случае компилятор не знает истинного размера.

Так же, как и при удалении массива, требуется помощь от программиста. Это делается добавлением виртуального деструктора к базовому классу Етр!оуее: с1азз Етргоуее ( риЫ1с: гоЫ* орегазог пеи (зйе !); гоЫ орегазог аегеге(гоЫ", з(зе з) Ыгзиа! -Етр(оуее ( ); уу ... ): Подойдет даже пустой деструктор: Етр1оуее:: -Етр1оуее ( ) ( ] В случае виртуальных деструкторов необходимый для освобождения размер памяти так или иначе связывается с вызовом правильного деструктора (который знает истинный размер объекта). Присутствие в классе Етр!оуее виртуального деструктора гарантирует, что каждый производный класс будет располагать деструктором (обеспечивающим информацию о правильном размере объекта), даже если таковой в этом производном классе явно и не определяется.

Например: гоЫу () ( Етр!оуее" р= пет Мапааег; !)е1есе р; УУ теперь все правильно (Етр!оуее - полиморфный) Выделение кода осуществляется при помощи генерируемого компилятором вы- зова Етр!оуее:: орегатг пеп (з(зеоЯМапаяег) ) обязаны это делать) и игнорировать аргумент типа з!зе ! у функции орега!ог Ие1е!е() . Последний подход затрудняет повышение производительности (в плане скорости и непроизводительных расходов памяти) механизмов работы с памятью по сравнению с таковыми же для общего назначения. Как компилятор узнает правильное значение второго аргумента (размер удаляемого объекта) при вызове функции орега!ог ~!е(е!е ( )? Пока операция г1е1е!е ассоциируется с истинным типом объекта, это просто. Однако так бывает далеко не всегда: ) 5.6.

Свободная память а освобождение памяти — при помощи другого генерируемого компилятором вызова: Етр1оуее:: орегатг ((е(е(е (р, в(еео/' (Ма»олег) ) Другими словами, если вы хотите предоставить собственную пару аллокатор/деаллокатор, которая корректно работает с производными классами, то вы должны либо определить виртуальный деструктор в базовом классе, либо воздержаться от использования аргумента типа в[ге ( в деаллокаторе. Естественно, можно было бы спроектировать этот аспект языка таким образом, чтобы избавить программиста от сопутствующих сложностей. Но тогда бы и не было возможности осуществлять оптимизацию работы с памятью, присущую лишь менее безопасным системам. 15.6.1.

Выделение памяти под массивы Функции прего(ог ае»() и орегаюг (!е!е(е() позволяют программисту брать на себя управление выделением/освобождением памяти для индивидуальных объектов; функции прага(огпе(г [] () и прего(ог(1е1е(е [] () играюттуже рольдля массивов. Например: с1аи Етр(оуее ( рибяс: юп(* прего(ог пе(г [ ] ( в((е () ( юЫ орега(ог ((е(е(е [ ] (во(а«, вие () (( ... юИ/'((п( в) Етр(оуее* р = пе(г Етр!оуее [в] ( р... Ие1е(е [] р( ) В этом случае память выделяется при помощи вызова Етр(оуее:: прего(ог пе(г [ ] (в((ео/" (Етр!оуее) "вч1е((а) [где (1е1(а — некоторая вспомогательная память, зависящая от реализации), а осво- бождается память при помощи вызова Етр(оуее:: орега(ог ((е(е(е [ ] (р) ( р освобождаем в«в(еео~(Етр!оуее)+((е((а байт Количество элементов а и избыточная память (1е1(а запоминаются системой.

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

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

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

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