Главная » Просмотр файлов » С. Мейерс - Эффективный и современный C++

С. Мейерс - Эффективный и современный C++ (1114942), страница 20

Файл №1114942 С. Мейерс - Эффективный и современный C++ (С. Мейерс - Эффективный и современный C++) 20 страницаС. Мейерс - Эффективный и современный C++ (1114942) страница 202019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Ссылочные ква­лификаторы функции-члена являются одной из менее известных возможностейС++ 1 1 , так что не удивляйтесь, если вы до сих пор ничего о них не слышали. Онипозволяют ограничить использование функции-члена только объектами lvalue илитолько объектами rvalue.

Для использования этих квалификаторов функции-чле­ны не обязаны быть виртуальными.class WidgetpuЫic :void doWork ( ) & ;Эта версияесли *thisЭта версияесли * thisdoWork применима , толькопредставляет собой lvaluedoWork применима , толькопредставляет собой rvalue};11111111Widget makeWidget ( ) ;11 Фабричная функция ( возвращает rvalue )void doWork ( ) &&;З.б.

Объявляйте перекрывающие функции как override89Widget w ;11 Обычный объект ( lvalue )111111rnakeWidget ( ) . doWork ( ) ;11w . doWork ( ) ;Вызов(т.е.Вызов(т.е.Widget :Widget :Widget :Widget :: doWork: doWork: doWork: doWorkдля lvalue&)ДЛЯ rvalue&&)Позже я расскажу побольше о функциях-членах с о ссылочными квалификатора­ми, а пока что просто заметим, что если виртуальная функция в базовом клас­се имеет ссылочный квалификатор, то производный класс, перекрывающий этуфункцию, должен иметь тот же ссылочный квалификатор. Если это не так, объяв­ленные функции все еще остаются в производном классе, но они ничего не пере­крывают в базовом классе.Все эти требования к перекрытию означают, что маленькие ошибки могут привестик большим последствиям.

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

почему каждая функцияпроизводного класса не переопределяет функцию базового класса с тем же именем)?class Base {puЬlic :virtual void mfl ( ) cons t ;virtual void mf2 ( int х ) ;virtual void mf3 ( ) & ;void mf4 ( ) const ;};class Derived : puЫic BasepuЬlic :virtual void mfl ( ) ;virtual void mf2 ( unsigned int х ) ;virtual void mf3 ( ) & & ;void mf4 ( ) cons t ;);Нужна помощь?•mfl объявлена как const в классе Base, но в классе Derived этого модификатора нет.•rnf2 получает аргумент типа int в классе Base, но в классе Deri ved она получаетаргумент типа uns igned int.90Гn ава 3. Переход к современному Ctt•mfЗ определена с квалификатором lvalue в классе Base и с квалификатором rvalueв классе De rived.•mf4 не объявлена в классе Base как vi rtua l.Вы можете подумать "На практике все это вызовет предупреждения компилятора, такчто мне не о чем беспокоиться': Может быть, это и так.

А может быть, и не так. В двух изпроверенных мною компиляторах код был принят без единой жалобы - в режиме, когдавсе предупреждения были включены. (Другие компиляторы выдавали предупрежденияо некоторых из проблем, но не обо всех одновременно.)Поскольку очень важно правильно объявить производный класс перекрывающим, нопри этом очень легко ошибиться, C++ l l дает вам возможность явно указать, что функ­ция производного класса предназначена для того, чтобы перекрывать функцию из базо­вого класса: ее можно объявить как override.

Применяя это ключевое слово к приведен­ному выше примеру, мы получим следующий производный класс:class Derived : puЬlic Base (puЬlic :virtual void mfl ( ) override;virtual void mf2 ( unsigned int х ) override;virtual void mf3 ( ) & & override;virtual void mf4 ( ) const overricle ;};Этот код компилироваться не будет, поскольку теперь компиляторы знают о том, что этифункции предназначены для перекрытия функций из базового класса, а потому могутопределить наличие описанных нами проблем. Это именно то, что нам надо, и потому выдолжны объявлять все свои перекрывающие функции как override.Код с использованием ove r r i de, который будет успешно скомпилирован, выглядитследующим образом (в предположении, что нашей целью является перекрытие функция­ми в классе Der i ved всех виртуальных функций в классе Base ) :class Base {puЬlic :virtual voidvirtual voidvirtual voidvirtual void};mfl ( ) const ;mf2 ( int х ) ;mf3 ( ) & ;mf4 ( ) const ;class Derived : puЫic Base {puЫ i c :vir tual void mf l ( ) const override ;virtual void mf2 (int х ) override ;virtual void mf3 ( ) & override ;void mf4 ( ) const override ; / / Слово virtual не мешает, но};/ / и не является обязательным3.6 .

Объяв ляйте перекрывающие функции как override91Обратите внимание, что в этом примере часть работы состояла в том, чтобы объявить mf 4в классе Base как виртуальную функцию. Большинство ошибок, связанных с перекрытием,совершаются в производном классе, но можно сделать такую ошибку и в базовом классе.Стратегия использования ключевого слова override во всех перекрытиях производно­го класса способна на большее, чем просто позволить компиляторам сообщать, когда функ­ции, которые должны быть перекрытиями, ничего не перекрывают. Они также могут по­мочь вам оценить последствия предполагаемого изменения сигнатуры виртуальной функ­ции в базовом классе. Если производные классы везде используют override, вы можетепросто изменить сигнатуру и перекомпилировать систему.

Вы увидите, какие повреждениянанесли своей системе (т.е. сколько классов перестали компилироваться), и после этогосможете принять решение, стоит ли изменение сигнатуры таких хлопот. Без override выдолжны были бы надеяться на наличие достаточно всеобъемлющих тестов, поскольку, какмы видели, виртуальные функции, которые предназначены перекрывать функции базовогокласса, но не делают этого, не приводят ни к какой диагностике со стороны компилятора.В С++ всегда имелись ключевые слова, но С++ 1 1 вводит два контекстных ключевыхслова (contextual keywords)override и f i nal'. Эти ключевые слова являются зарезер­вированными, но только в некоторых контекстах. В случае override оно имеет зарезерви­рованное значение только тогда, когда находится в конце объявления функции-члена. Этозначит, что если у вас есть старый код, который уже использовал имя override, его не надоизменять при переходе к С++ 1 1 :-c lass WarningpuЬlic :11 Потенциально старый класс из С++98void override ( ) ; / / Корректно как в С++98 , так и11 ( с тем же смыслом)вC+ + l l};Это все, что следует сказать об override, но это не все, что следует сказать о ссылоч­ных квалификаторах функций-членов.

Я обещал, что поговорю о них позже, и вот сейчаскак раз и настало это "позже':Если мы хотим написать функцию, которая принимает только аргументы, являющи­еся lvalue, мы объявляем параметр, который представляет собой неконстантную \vа\uе­ссылку:void doSomething (Widget& w) ; / / Принимает только lvalue WidgetЕсли же мы хотим написать функцию, которая принимает только аргументы, являющие­ся rva\ue, мы объявляем параметр, который представляет собой rvalue-ccылкy:void doSomething (Widget&& w) ; 11 Принимает только rvalue Widget-' Применение ключевого слова f i n a l к виртуальной функции препятствует перекрытию :нойфункции в производном классе. Ключевое слово final также может быть применено к классу;в этом случае класс стано11ится неприменимым в качестве базо11ого.92Гn ава 3.

Переход к современному С++Ссылочные квалификаторы функции-члена позволяют проводить такое же различиедля объектов, функции-члены кторых вызываются, т.е. * t h i s . Это точный аналог мо­дификатора const в конце объявления функции-члена, который указывает, что объект,для которого вызывается данная функция-член (т.е. *thi s), является const.Необходимость в функциях-членах со ссылочными квалификаторами нужна не такуж часто, но может и возникнуть.

Предположим, например, что наш класс Widget име­ет член-данные std : : vector, и мы предлагаем функцию доступа, которая обеспечиваетклиентам к нему непосредственный доступ:class Widget {puЫi c :using DataTypestd : : vector<douЫe>; / / См . информацию о11 using в разделе 3 . 3DataType& data ( ) { return value s ; }private :DataType values ;};Вряд ли это наиболее инкапсулированный дизайн, который видел свет, но оставимэтот вопрос в стороне и рассмотрим, что происходит в следующем клиентском коде:Widget w;auto valsl=w .

data ( ) ;/ / Копирует w . values в valslВозвращаемый тип W i dget : : data представляет собой \vа\uе-ссылку (чтобы быть точ­ным - std: : vector<douЬle>&), а поскольку \vа\uе-ссылки представляют собой lva\ue, мыинициализируем v a l s l из \vа\uе. Таким образом, val s l создается копирующим конструк­тором из w .

va lues, как и утверждает комментарий.Теперь предположим, что у нас имеется фабричная функция, которая создает Widget:Widget makeWidget ( ) ;и мы хотим инициализировать переменную с помощью s t d : : vector в W i dget, возвра­щенном из makeWidget:auto vals2=makeWidget ( ) . data ( } ; // Копирование значений в// Widget в vals2И вновь Widget s : : data возвращает \vа\uе-ссылку, и вновь \vа\uе-ссылка представляетсобой lvalue, так что наш новый объект (va l s 2 ) опять является копией, построенной изva lues в объекте Widget. Однако в этот раз Widget представляет собой временный объект,возвращенный из ma keWidget (т.е.

представляет собой rvalue), так что копирование в негоstd : : vector представляет собой напрасную трату времени. Предпочтительнее выполнитьперемещение, но, поскольку data возвращается как \vа\uе-ссылка, правила С++ требуют,чтобы компиляторы генерировали код для копирования. (Имеется некоторый маневр3.6. Объяв л яйте перекрывающие функции как override93для оптимизации на основе правила "как если бы"4, но было бы глупо полагаться та то, чтоваш компилятор найдет способ им воспользоваться.)Нам необходим способ указать, что, когда data вызывается для Widget, являющего­ся rvalue, результат также будет представлять собой rvalue. Использование ссылочныхквалификаторов для перегрузки data для Widget, являющихся lvalue и rvalue, делает этовозможным:class WidgetpuЫic :using DataTypestd : : vector<douЫe>;DataType& data ( ) &{ return values ; }DataType&& data ( ) &&{ return std: : move (values ) ;/ / Для lvalue11 возвращает11 Для rvalue11 возвращаетWidge t ,lvalueWidge t ,rvalueprivate :DataType value s ;};Обратите внимание на разные возвращаемые типы перегрузок data.

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

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

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

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