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

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

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

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

Генерация специапь н ых функций-чпеновВ официальной терминологии С++ специальные функции-членыэто те функции­члены, которые С++ готов генерировать сам. С ++ 98 включает четыре такие функции:конструктор по умолчанию, деструктор, копирующий конструктор и оператор копирую­щего присваивания. Эти функции создаются, только если они необходимы, т.е. если не­который код использует их без их явного объявления в классе.

Конструктор по умолча­нию генерируется только в том случае, если в классе не объявлен ни один конструктор.(Это предотвращает компиляторы от создания конструктора по умолчанию для класса,для которого вы указали, что конструктору требуются аргументы. Сгенерированные-1 16Глава 3 . Переход к современному С++специальные функции-члены неявно являются открытыми и встраиваемыми; они так­же являются не виртуальными, если только таковой функцией не является деструкторпроизводного класса, унаследованного от базового класса с виртуальным деструктором.В этом случае генерируемый компилятором деструктор производного класса также явля­ется виртуальным.Ну, конечно же, вы отлично все это знаете.

Да, да, древняя история: Месопотамия,династия Цинь, Владимир Красное Солнышко, FORTRAN, С++98 . . . Но времена изме­нились, а с ними изменились и правила генерации специальных функций-членов в С++.Важно быть в курсе новых правил, потому что мало вещей имеют такое же важное значе­ние для эффективного программирования на С++, как знание о том, когда компиляторымолча добавляют функции-члены в ваши классы.Что касается С++ 1 1 , то в клуб специальных функций-членов приняты два новыхигрока: перемещающий конструктор и оператор перемещающего присваивания. Их сиг­натуры имеют следующий вид:class WidgetpuЫ i c :Widg8t (Widg8t&& rhs) ;/ / Перемещающий: конструкторWidget& operator= (Widqet&& rhs) ; 11 Оператор перемещающего/ / присваивания);Правила, регулирующие их создание и поведение, аналогичны правилам для их ко­пирующих двойников.

Перемещающие операции генерируются только если они необхо­димы, и если они генерируются, то выполняют "почленное перемещение" нестатическихчленов-данных класса. Это означает, что перемещающий конструктор создает каждыйнестатический член-данные класса из соответствующего члена его параметра rhs с по­мощью перемещения, а оператор перемещающего присваивания выполняет перемещаю­щее присваивание каждого нестатического члена-данных из переданного ему параметра.Перемещающий конструктор также выполняет перемещающее конструирование частейбазового класса (если таковые имеются), а оператор перемещающего присваивания вы­полняет соответственно перемещающее присваивание частей базового класса.Когда я говорю о перемещающей операции над членом-данными или базовым клас­сом, нет никакой гарантии, что перемещение в действительности имеет место.

"Почлен­ные перемещения" в действительности представляют собой запросы на почленное пере­мещение, поскольку типы, которые не могут быть перемещены (т.е. не обладают под­держкой операций перемещения; например, таковыми являются большинство старыхклассов С++98), будут "перемещены" с помощью операций копирования. Сердцем каж­дого почленного "перемещения" является применение std : : move к объекту, из котороговыполняется перемещение, а результат используется в процессе разрешения перегрузкифункций для выяснения, должно ли выполняться перемещение или копирование.

Этотпроцесс детально описывается в разделе 5. 1 . В этом разделе просто помните, что почлен­ное перемещение состоит из операций перемещения для тех членов-данных и базовых3.1 1 .Генерация специальных функций-чл енов117классов, которые поддерживают перемещающие операции, и из операций копированиядля тех, которые перемещающие операции не поддерживают.Как и в случае с копирующими операциями, перемещающие операции не генерируют­ся, если вы сами их не объявляете. Однако точные условия, при которых они генериру­ются, несколько отличаются от условий для копирующих операций.Две копирующие операции независимы одна от другой: объявление одной не пре­пятствует компилятору генерировать другую.

Так что если вы объявляете копирующийконструктор, но не копирующий оператор присваивания, а затем пишете код, которомутребуется копирующее присваивание, то компиляторы будут генерировать оператор ко­пирующего присваивания вместо вас. Аналогично, если вы объявили оператор копирую­щего присваивания, но не копирующий конструктор, а вашему коду нужен копирующийконструктор, то последний будет сгенерирован компилятором вместо вас.

Это правилоработало в С++98 и остается справедливым в C++ l l .Две перемещающие операции н е являются независимыми. Если вы объявите однуиз них, это не позволит компиляторам сгенерировать вторую. Это объясняется тем, чтоесли вы объявляете, скажем, перемещающий конструктор для вашего класса, то вы ука­зываете, что есть что-то, что при перемещающем конструировании должно быть реа­лизовано иначе, чем почленное перемещение по умолчанию, генерируемое компилято­рами.

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

Объявление в классе перемеща­ющей операции (конструктора или присваивания) приводит к тому, что компиляторыне генерируют копирующие операции. (Копирующие операции отключаются с помощьюих удаления; см. раздел 3.5). В конце концов, если почленное перемещение не являет­ся корректным способом перемещения, то нет причин ожидать, что почленное копи­рование окажется корректным способом копирования.

Это выглядит как возможноенарушение работоспособности кода С++98, поскольку условия, при которых разреше­на генерация операций копирования, являются более ограничивающими в C++ l l , чемв С++98, но на самом деле это не так. Код С++98 не может иметь перемещающие опера­ции, поскольку в С++98 нет такого понятия, как "перемещение" объектов. Единствен­ный способ для старого класса иметь пользовательские перемещающие операции - этоесли они будут добавлены в коде С++ 1 1 . Но классы, которые изменены таким образом,1 18Гnава 3 . Переход к совреме нн ому С++чтобы использовать преимущества семантики перемещений, обязаны играть по прави­лам С++ 1 1 , касающимся генерации специальных функций-членов.Вероятно, вы слышали о рекомендации о большой тройке.

Она утверждает, что есливы объявили хотя бы одну из трех операций - копирующий конструктор, копирующийоператор присваивания или деструктор, - то вы должны объявить все три операции.Это правило вытекает из наблюдения, что необходимость изменения смысла копирую­щей операции почти всегда подразумевает, что ( l ) какое бы управление ресурсами ни­выполнялось в одной копирующей операции, вероятно, такое же управление ресурсамипотребуется и во второй копирующей операции; и (2) деструктор класса также долженучаствовать в управлении ресурсами (обычно - освобождать их). Классическим управ­ляемым ресурсом является память, и именно поэтому все классы стандартной библио­теки, управляющие памятью (например, контейнеры STL, управляющие динамическойпамятью), объявляют всю "большую тройку": обе копирующие операции и деструктор.Следствием правила большой тройки является то, что наличие пользовательскогодеструктора указывает на вероятную неприменимость простого почленного копирова­ния для копирующих операций класса.

Это, в свою очередь, предполагает, что если классобъявляет деструктор, то копирующие операции, по всей вероятности, не должны гене­рироваться автоматически, так как они будут выполнять неверные действия. Во временапринятия С++98 важность этих рассуждений не была оценена должным образом, такчто в С++98 наличие пользовательского деструктора не влияло на генерацию компиля­торами копирующих операций. Это правило перешло и в С++ 1 1 , но только потому, чтоограничение условий, при которых могут автоматически генерироваться копирующиеоперации, сделает некомпилируемым слишком большое количество старого кода.Однако рассуждения, лежащие в основе "правила большой тройки': остаются в силе,и это, в сочетании с наблюдением, что объявление копирующей операции исключает не­явную генерацию перемещающих операций, обосновывает тот факт, что С++ 1 1 не гене­рирует операции перемещения для класса с пользовательским деструктором.Таким образом, перемещающие операции генерируются (при необходимости)для классов, только если выполняются три следующие условия:•в классе не объявлены никакие копирующие операции;•в классе не объявлены никакие перемещающие операции;•в классе не объявлен деструктор.В некоторый момент аналогичные правила могут быть распространены на копиру­ющие операции, поскольку C++ l l выступает против автоматической генерации копи­рующих операций для классов, объявляющих копирующую операцию или деструктор.Это означает, что если у вас есть код, зависящий от генерации копирующих операцийв классе с объявленным деструктором или одной из копирующих операций, то вы долж­ны рассмотреть обновление таких классов для устранения указанной зависимости.

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

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

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

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