cpp-oop (823968), страница 21

Файл №823968 cpp-oop (Методические пособия по C++ Г.С.Иванова 3 части) 21 страницаcpp-oop (823968) страница 212021-07-27СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Однако работая с указателями программисты, особенно начинающие, допускаютзначительное количество ошибок, приводящих к нарушениям защиты и «утечкам»памяти. Причины этого кроются в особенностях языковых средств, используемых приработе с динамическими объктами. Так:•при использовании указателей ответственность за выделение памяти под объекти ее освобождение целиком лежит на программисте;•на один и тот же объект может ссылаться несколько не связанных между собойуказателей,следовательновозможноналичиеуказателей,ссылающихсянаосвобождённые или перемещённые объекты;•нет никакой возможности проверить, указывает ли ненулевой указатель накорректные данные, либо «в никуда»;•указатель на единичный объект и указатель на массив объектов в С++ никак неотличаются друг от друга.Разработать код, который корректно освобождает выделенную динамическуюпамять, непросто.

При этом надо предусмотреть освобождение памяти не только принормальном вычислительном процессе, но и при аварийном завершении.Так простейшая процедура, в которой создается динамический объект и вызываетсяего метод:void proc(){B *temp = new B;B->func();delete temp;// выделение памяти под объект// вызов метода для объекта// освобождение памяти}ОглавлениеИванова Г.С., Ничушкина Т.Н.

«Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»163с учетом необходимости освобождения памяти при аварийном завершении существенноудлиняется:void proc(){B *temp = NULL;try{temp = new B; // выделение памяти под объектB->func();// вызов метода для объекта}catch (...)// перехват всех исключений{delete temp;// освобождение памяти при аварийном// завершении процедурыthrow;// возобновление исключения}delete temp;// освобождение памяти при нормальном// завершении процедуры}Еще сложнее обеспечить освобождение памяти при возникновении ошибки вконструкторе.

Язык С++ обеспечивает корректное освобождение памяти, выделенной подобъект, при аварийном завершении программы только, если этот объект полностьюсконструирован. Если же конструирование объекта не завершено, т. е. исключениезафиксировано в конструкторе, то автоматического освобождения памяти,ужевыделенной под часть объекта, выполнено не будет, и, следовательно, произойдет«утечка» памяти. Например, для класса, описанного ниже, при возникновенииисключения в конструкторе часть памяти останется недоступной.class D{private:A * a;B * b;ОглавлениеИванова Г.С., Ничушкина Т.Н.

«Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»164public:D() : a(new A), b(new B) { }~D() throw(){delete a;delete b; }};Обеспечить корректное освобождение памяти для данного класса существенносложнее.В соответствии с этим естественным является женлание упростить работу сдинамическимиобъектами.Очевидноерешение–вместообычногоуказателяиспользовать объект-указатель, хранящий адрес и освобождающий память в своёмдеструкторе.

Данная технология называется Resource Acquisition Is Initialization (RAII) –«Захват ресурса есть инициализация». Её смысл заключается в том, что захват ресурсасовмещается с инициализацией объекта, а освобождение – с уничтожением объекта.Именно таким поведением обладает шаблон auto_ptr из стандартной библиотеки C++.ОглавлениеИванова Г.С., Ничушкина Т.Н. «Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»1658.2Шаблон auto_ptrШаблон auto_ptr включен в стандартную библиотеку <memory> языка C++ иопределен в адресном пространстве std.

Это единственный «умный» указатель,включенный в нынешний стандарт C++.Шаблон предусматривает следующие методы:• конструкторы простой и копирующий;• деструктор;• get() – возвращает хранимый адрес;• release() – возвращает хранимый адрес и записывает вместо него NULL вобъект-указатель;• reset() – освобождает память, адрес которой хранится в указателе-объекте, и,если параметр – новый динамический объект указан, то записывает в негоновый адрес, если параметр не указан, то адрес устанавливается в NULL.Шаблон также переопределяет следующие операции:• operator=() – операцию присваивания;• operator*() – операцию доступа к адресуемому объекту по адресу;• operator->() – операцию доступа к адресуемому объекту по адресу;• operatorauto_ptr<Other>–операциюпреобразованияуказателяauto_ptr одного типа к указателю auto_ptr другого типа;• operator auto_ptr_ref<Other> –операцию преобразования указателяauto_ptr одного типа к указателю auto_ptr_ref другого типа.Чтобы построить класс, используя шаблон, необходимо задать тип динамическогообъекта, который будет храниться в объекте указателе.Пример 8.1.

Создание объекта-указателя, его использование и перезапись.#include <memory>#include <iostream>#include <conio.h>using namespace std;class AОглавлениеИванова Г.С., Ничушкина Т.Н. «Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»166{public:int x;A(int X):x(X){}A(){}~A(){cout<<"destructor"<<endl;}};void main(){auto_ptr<A> temp1; // неинициализированный объект-указательauto_ptr<A> temp(new A(1)); // инициализированный объект-указательA &a= *temp; // ссылка на хранимый объектcout<<"A.x="<<a.x<<endl;A *ptr = temp.get();// указатель на хранимый объектcout<<"ptr="<<ptr<<endl;temp.reset(); // освобождение указателяA *ptr1 = temp.get();// указатель на хранимый объектcout<<"ptr1="<<ptr1<<endl;getch();}Результат выполнения программы:A.x=1ptr=00396520destructorptr1=00000000Следует помнить, что шаблон определяет объект-указатель, реализующий семантику«владения», при которой всегда существует только один объект-указатель, хранящийадрес выделенного фрагмента динамической памяти.

Для этого реализация шаблонаобеспечивает «разрушающее» копирование, при котором копируемый адрес уничтожаетсяпосле переписи в новый объект-указатель. Таким образом становится невозможнымОглавлениеИванова Г.С., Ничушкина Т.Н. «Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»167наличие двух и более объектов-указателей, адресующих один объект, и исключаютсяошибки, связанные с повторным освобождением памяти объекта.Пример 8.2. Невозможность создания копии объекта-указателя auto_ptr.#include <conio.h>#include <memory>class A{public:void f (){}};int main(){std::auto_ptr<A> temp1(new A); // объявление и инициализация// объекта-указателяtemp1->f();// вызов метода - выполняется нормальноstd::auto_ptr<A> temp2(temp1); // объявление и инициализация// второго объекта-указателяtemp1->f();// вызов метода – не возможен, так как адрес// разрушен при копированииgetch();}Невозможность создания копий адреса не позволяет использовать указатели,построенные по шаблону auto_ptr, для создания списковых структур, поскольку впроцессе обработки список будет разрушаться.

Выходом из этой ситуации являетсяиспользование умного указателя с подсчётом ссылок – shared_ptr.ОглавлениеИванова Г.С., Ничушкина Т.Н. «Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»1688.3Шаблон shared_ptrШаблон shared_ptr позволяет создавать объекты-указатели, отличающиеся отобъектов-указателей auto_ptrв основном методикой копирования. Хотя данныйшаблон в настоящее время не включен в стандарт, он реализован в библиотеке boost,которая может быть интегрирована в Visual Studio 2008.Шаблон определен в адресном пространстве boost.

Он реализует разделяемое«владение» с подсчётом ссылок, при котором очередное копирование адреса приводит кувеличению специального счетчика на единицу. В свою очередь при уменьшенииколичества указателей-объектов, связанных с динамическим объектом, значение счетчикауменьшается. Все объекты-уазатели при этом равноценно владеют объектом. Согласноиспользуемой методике адресуемый объект освобождает занимаемую им память приотключении последнего адресующего его объекта-указателя.Шаблон также позволяет при инициализации задавать процедуру удаленияdeleter(), что может быть полезно для классов, требующих выполнения нестандартныхдействий при удалении динамического объекта.Кроме того, шаблон предусматривает оператор неявного преобразования объектауказателя в bool, что позволяет выполнять проверку указателя по правилам С++,например:boost::shared_ptr<A> p = ptr;if (p) { // если указатель содержит действующий адрес}При работе с объектами-указателями, построенными по шаблону shared_ptrпрограммисты часто допускают одну и ту же ошибку, создавая несколько разделяемыхуказателей на один объект без их копирования, например:A ptr_obj = new A(); // динамический объект{ // новый блокshared_ptr<A> ptr1(ptr_obj); // разделяемый указатель на// объектshared_ptr<A> ptr2(ptr_obj); // второй разделяемыйОглавлениеИванова Г.С., Ничушкина Т.Н.

«Объектно-ориентированное программирование на языке C++ в среде Microsoft Visual Studio 2008»169// указатель на тот же объект...} // в этом месте программа выдает ошибку обращения к// несуществующему объектуДело в том, что инициализация разделяемых указателей обычным указателем наобъект приводит к созданию двух счетчиков ссылок, независящих друг от друга. Каждыйиз этих счетчиков обнуляется в конце блока, поскольку оба объекта-указателяуничтожаются. Это приводит к двум попыткам удаления одного динамического объекта.Первая срабатывает, вторая – приводит к ошибке (!).Правильным решением было бы создавать оба объекта-указателя копированиемисходного объекта-указателя, тогда будет использован копирующий конструктор шаблонаshared_ptr, и, соответственно, счетчик будет один. Это приведет к единственномуудалению объекта при обнулении счетчика.Пример 8.3.

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

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

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

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