Главная » Просмотр файлов » С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс

С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944), страница 65

Файл №1114944 С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс) 65 страницаС.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944) страница 652019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

При этом время выполнения не увеличивается. Применение встроенныхфункций (которые подставляются по месту вызова) позволило сделать использованиеобъекта auto_ptr немногим более дорогим, чем непосредственное употреблениеуказателя.Что произойдет, если мы проинициализируем pstr_auto2 значением pstr_auto,// кто несет ответственность за уничтожение строки?который является объектом auto_ptr, указывающим на строку?auto_ptr< string > pstr_auto2( pstr_auto );Представим, что мы непосредственно инициализировали один указатель на строкудругим:string *pstr_type2( pstr_type );Оба указателя теперь содержат адрес одной и той же строки, и мы должны бытьвнимательными, чтобы не удалить строку дважды.В противоположность этому шаблон класса auto_ptr поддерживает понятие владения.Когда мы определили pstr_auto, он стал владельцем строки, адресом которой былинициализирован, и принял на себя ответственность за ее уничтожение.Вопрос в том, кто станет владельцем строки, когда мы инициализируем pstr_auto2адресом, указывающим на тот же объект, что и pstr_auto? Нежелательно, чтобы обаобъекта владели одной и той же строкой: это вернет нас к проблемам повторногоудаления, от которых мы стремились уйти с помощью шаблона класса auto_ptr.Когда один объект auto_ptr инициализируется другим или получает его значение врезультате присваивания, одновременно он получает и право владения адресуемымобъектом.

Объект auto_ptr, стоящий справа от оператора присваивания, передает правоС++ для начинающихвладения и ответственность auto_ptr, стоящему слева. В нашем примереответственность за уничтожение строки несет pstr_auto2, а не pstr_auto. pstr_autoбольше не может употребляться для ссылки на эту строку.auto_ptr< int > p1( new int( 1024 ) );Аналогично ведет себя и операция присваивания. Пусть у нас есть два объекта auto_ptr:auto_ptr< int > p2( new int( 2048 ) );Мы можем скопировать один объекта auto_ptr в другой с помощью этой операции:p1 = p2;Перед присваиванием объект, на который ссылался p1, удаляется.После присваивания p1 владеет объектом типа int со значением 2048.

p2 больше неможет использоваться как ссылка на этот объект.Третья форма определения объекта auto_ptr создает его, но не инициализирует// пока не ссылается ни на какой объектзначением указателя на область памяти из хипа. Например:auto_ptr< int > p_auto_int;Поскольку p_auto_int не инициализирован адресом какого-либо объекта, значениехранящегося внутри него указателя равно 0. Разыменование таких указателей приводит к// ошибка: разыменование нулевого указателяif ( *p_auto_int != 1024 )непредсказуемому поведению программы:*p_auto_int = 1024;int *pi = 0;Обычный указатель можно проверить на равенство 0:if ( pi ! = 0 ) ...;А как проверить, адресует auto_ptr какой-либо объект или нет? Операция get()возвращает внутренний указатель, использующийся в объекте auto_ptr.

Значит, мы// проверяем, указывает ли p_auto_int на объектif ( p_auto_int.get() != 0 &&*p_auto_int != 1024 )должны применить следующую проверку:391С++ для начинающих*p_auto_int = 1024;Если auto_ptr ни на что не указывает, то как заставить его адресовать что-либо?Другими словами, как мы можем присвоить значение внутреннему указателю объектаelse// хорошо, присвоим ему значениеauto_ptr? Это делается с помощью операции reset(). Например:p_auto_int.reset( new int( 1024 ) );Объекту auto_ptr нельзя присвоить адрес объекта, созданного с помощью оператораvoid example() {// инициализируется нулем по умолчаниюauto_ptr< int > pi;{// не поддерживаетсяpi = new int( 5 ) ;}new:}В этом случае надо использовать функцию reset(), которой можно передать указательили 0, если мы хотим обнулить объект auto_ptr.

Если auto_ptr указывает на объект иявляется его владельцем, то этот объект уничтожается перед присваиванием новогоauto_ptr< string >pstr_auto( new string( "Brontosaurus" ) );// "Brontosaurus" уничтожается перед присваиваниемзначения внутреннему указателю auto_ptr. Например:pstr_auto.reset( new string( "Long-neck" ) );В последнем случае лучше, используя операцию assign(), присвоить новое значение// более эффективный способ присвоить новое значение// используем операцию assign()существующей строке, чем уничтожать одну строку и создавать другую:pstr_auto->assign( "Long-neck" );Одна из трудностей программирования состоит в том, что получить правильныйрезультат не всегда достаточно.

Иногда накладываются и временные ограничения. Такаямелочь, как удаление и создание заново строкового объекта, вместо использованияфункции assign() при определенных обстоятельствах может вызвать значительноезамедление работы. Подобные детали не должны вас беспокоить при проектировании, нопри доводке программы на них следует обращать внимание.392С++ для начинающихШаблон класса auto_ptr обеспечивает значительные удобства и безопасностьиспользования динамически выделяемой памяти. Однако все равно надо не терятьбдительности, чтобы не навлечь на себя неприятности:•нельзя инициализировать объект auto_ptr указателем, полученным не спомощью оператора new, или присвоить ему такое значение. В противном случаепосле применения к этому объекту оператора delete поведение программынепредсказуемо;•два объекта auto_ptr не должны получать во владение один и тот же объект.Очевидный способ допустить такую ошибку – присвоить одно значение двумauto_ptr< string >pstr_auto( new string( "Brontosaurus" ) );// ошибка: теперь оба указывают на один объект// и оба являются его владельцамиобъектам.

Менее очевидный – с помощью операции get(). Вот пример:auto_ptr< string > pstr_auto2( pstr_auto.get() );Операция release() гарантирует, что несколько указателей не являютсявладельцами одного и того же объекта. release() не только возвращает адресобъекта, на который ссылается auto_ptr, но и передает владение им.// правильно: оба указывают на один объект,// но pstr_auto больше не является его владельцемauto_ptr< string >Предыдущий фрагмент кода нужно переписать так:pstr_auto2( pstr_auto.release() );8.4.3. Динамическое создание и уничтожение массивовОператор new может выделить из хипа память для размещения массива. В этом случаепосле спецификатора типа в квадратных скобках указывается размер массива. Он можетбыть задан сколь угодно сложным выражением.

new возвращает указатель на первый// создание единственного объекта типа int// с начальным значением 1024int *pi = new int( 1024 );// создание массива из 1024 элементов// элементы не инициализируютсяint *pia = new int[ 1024 ];// создание двумерного массива из 4x1024 элементовэлемент массива. Например:int (*pia2)[ 1024 ] = new int[ 4 ][ 1024 ];pi содержит адрес единственного элемента типа int, инициализированного значением1024; pia – адрес первого элемента массива из 1024 элементов; pia2 – адрес начала393С++ для начинающих394массива, содержащего четыре массива по 1024 элемента, т.е.

pia2 адресует 4096элементов.В общем случае массив, размещаемый в хипе, не может быть инициализирован. (Вразделе 15.8 мы покажем, как с помощью конструктора по умолчанию присвоитьначальное значение динамическому массиву объектов типа класса.) Задаватьинициализатор при выделении оператором new памяти под массив не разрешается.Массиву элементов встроенного типа, размещенному в хипе, начальные значенияfor (int index = 0; index < 1024; ++index )присваиваются с помощью цикла for:pia[ index ] = 0;Основное преимущество динамического массива состоит в том, что количество элементовв его первом измерении не обязано быть константой, т.е. может не быть известным вовремя компиляции. Для массивов, определяемых в локальной или глобальной областивидимости, это не так: здесь размер задавать необходимо.Например, если указатель в ходе выполнения программы ссылается на разные C-строки,то область памяти под текущую строку обычно выделяется динамически и ее размеропределяется в зависимости от длины строки.

Как правило, это более эффективно, чемсоздавать массив фиксированного размера, способный вместить самую длинную строку:ведь все остальные строки могут быть значительно короче. Более того, программа можетаварийно завершиться, если длина хотя бы одной из строк превысит отведенный лимит.Оператор new допустимо использовать для задания первого измерения массива спомощью значения, вычисляемого во время выполнения. Предположим, у нас естьconst char *noerr = "success";// ...const char *err189 = "Error: a function declaration must "следующие C-строки:"specify a function return type!";Размер создаваемого с помощью оператора new массива может быть задан значением,#include <cstring>const char *errorTxt;if (errorFound)errorTxt = errl89;elseerrorTxt = noerr;int dimension = strlen( errorTxt ) + 1;char *strl = new char[ dimension ];// копируем текст ошибки в strlвычисляемым во время выполнения:strcpy( strl, errorTxt );С++ для начинающих// обычная для С++ идиома,// иногда удивляющая начинающих программистовdimension разрешается заменить выражением:char *strl = new char[ str1en( errorTxt ) + 1 ];Единица, прибавляемая к значению, которое возвращает strlen(), необходима для учетазавершающего нулевого символа в C-строке.

Отсутствие этой единицы – весьмараспространенная ошибка, которую достаточно трудно обнаружить, поскольку онапроявляет себя косвенно: происходит затирание какой-либо другой области программы.Почему? Большинство функций, которые обрабатывают массивы, представляющие собойС-строки символов, пробегают по элементам, пока не встретят завершающий нуль.Если в конце строки нуля нет, то возможно чтение или запись в случайную областьпамяти. Избежать подобных проблем позволяет класс string из стандартной библиотекиС++.Отметим, что только первое измерение массива, создаваемого с помощью оператора new,может быть задано значением, вычисляемым во время выполнения. Остальные измеренияint getDim();// создание двумерного массиваint (*pia3)[ 1024 ] = new int[ getDim() ][ 1024 ]; // правильно// ошибка: второе измерение задано не константойдолжны задаваться константами, известными во время компиляции. Например:int **pia4 = new int[ 4 ][ getDim() ];Оператор delete для уничтожения массива имеет следующую форму:delete[] str1;Пустые квадратные скобки необходимы.

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

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

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

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