4 (972472)

Файл №972472 4 (Семинары и упражнения)4 (972472)2019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла

Семинар 4. Дружественные функции.Динамическое распределение памяти.Перегрузкаоператоров.1. Дружественные функцииДружественные функции обладает такими же правами доступа к данным класса, как и егометоды (функции-элементы класса).Пример. Функция сравнения длин двух векторов.const Vector & comp2(const Vector & v1, const Vector & v2){if (v1.x*v1.x + v1.y*v1.y > v2.x*v2.x + v2.y*v2.y ) return v1;else return v2;}void main(){Vector v1(1.,1.);Vector v2(2.,2.);Vector v3 = comp2(v1,v2);v3.show();}Функция comp2 не принадлежит классу (нет модификатора Vector::) и, соответственно,не является методом этого класса. Может ли она, тем не менее, иметь доступ к даннымкласса? – Может, если ее объявить в этом классе дружественной:class Vector{…public:friend const Vector & comp2(const Vector &, const Vector &);…}(Упражнение С4_1)2.

Перегрузка операторовДля сложения двух векторов можно написать метод sum, например:Vector Vector::sum(const Vector v) const {return Vector(x + v.x, y + v.y);}и сложение будет выглядеть так:Vector v3 = v1.sum(v2);Между тем, сложить две целочисленные переменные a и b или переменные любогодругого базового типа можно довольно просто, используя оператор + :c = a + b;Нельзя ли этот оператор приспособить (перегрузить) для сложения новых типов данных,которыми являются классы? – Можно. В Си++ можно перегрузить почти все стандартныеоператоры (кроме ., .*, ::, ?:, sizeof). Для этого нужно написать специальную(операторную) функцию, которая будет вызвана при перегрузке соответствующегооператора.Для примера перегрузим оператор + так, чтобы при его использовании с двумя векторамирезультатом был третий вектор, равный сумме двух исходных.

Операторная функцияимеет вид: operatorоп (список_аргументов). Добавляем в класс прототип этой функции:class Vector{public:Vector operator+(const Vector) const;…}и пишем саму функцию:Vector Vector::operator+(const Vector v) const{return Vector(x + v.x, y + v.y);}Фактически, мы просто заменили имя функции-элемента sum на operator+. По-прежнему,использование модификаторов const гарантирует неизменность исходных векторов.Теперь складывать вектора можно следующим образом:Vector v1(5.,1.);Vector v2(2.,2.);Vector v3 = v1+v2;(*)Примечание.

Порядок следования операндов, в общем случае, важен для операторнойфункции. К первому операнду (v1) операторная функция-элемент имеет неявный доступ,как к объекту, для которого она вызвана, и обращение к данным происходит напрямую.Ко второму операнду (v2) доступ организован явным образом, как к формальномупараметру функции. Это хорошо видно, если выражение (*) записать в эквивалентномфункциональном виде:Vector v3 = v1.operator+(v2);3. Дружественная операторная функцияОператор может быть перегружен не только с помощью операторной функции-элемента,но и с помощью дружественной операторной функции. В последнем случае, перегрузкатого же оператора + для двух векторов может быть выполнена так:Vector operator+(const Vector v1, const Vector v2){return Vector(v1.x + v2.x, v1.y + v2.y);}при одновременном объявлении в классе Vector этой функции дружественной:friend Vector operator+(const Vector, const Vector);Примечание.

Следующие операторы могут быть перегружены только с помощьюфункции-элемента: =, (), [],->.(Упражнения С4_2, С4_3, С4_4)24. Перегрузка оператора вывода в поток <<Для удобства вывода значений координат вектора желательно иметь возможность делатьэто стандартным образом с помощью оператора <<.У оператора вывода в поток << два операнда. Первый (cout) - это объект класса ostream,второй операнд будет объектом класса Vector. Операторная функция может иметь вид:void operator<<(ostream & os, const Vector & v){os << "x = " << v.x << ", y = " << v.y ;}В классе Vector её следует объявить дружественной.

Однако такая перегрузка не позволитиспользовать выражения с цепочкой операторов вывода << вида:cout << v1 << endl;Чтобы реализовать такую возможность нужно, чтобы перегруженный оператор <<возвращал объект класса ostream. Улучшенный вариант операторной функции имеет вид:ostream & operator<<(ostream & os, const Vector & v){os << "x = " << v.x << ", y = " << v.y ;return os;}(Упражнение С4_5)5. Приведение к типу классаБазовые типы могут быть преобразованы друг в друга явным образом, например:int i = 10;double d = (double) i; или double d = double (i);или неявным:double d = i;Аналогичное приведение типа для класса осуществляется путем вызова конструктора содним параметром.

Неявное приведение типа в выраженииVector v = 10;(**)эквивалентно выражению (явное преобразование)Vector v = Vector(10);Примечание. Неявное преобразование (**) можно запретить, если при объявлениипрототипа конструктора с одним параметром указать модификатор explicit.6. Функции преобразованияОбратное преобразование из типа класса осуществляется с помощью специальной формыоператорной функции - функции преобразования:operator имя_типа();Функция преобразования должна быть методом класса без аргументов и не иметь явноговозвращаемого типа, но, тем не менее, возвращать указанный (имя_типа) тип.

Например,функция преобразования в тип double должна иметь следующий прототип:operator double();37. Конструктор копирования и оператор присваиванияVector v1;//вызывается конструктор по умолчанию для создания объекта v1.Vector v2 = v1; //для создания объекта v2 вызывается конструктор копирования.v2 = v1;// оператор присваивания (вызывается операторная функция присваивания).По умолчанию, как конструктор копирования, так и оператор присваивания осуществляютпоэлементное копирование всех элементов данных одного объекта в другой. Это работаетдаже, если элемент данных является массивом, структурой или объектом другого класса.Например, если в класс Vector добавить элемент данных в виде массива:class Vector{private:double x;double y;char c[100];…}то данные объекта v2 из приведенного выше примера будут иметь такие же значения, каку объекта v1, включая одинаковые значения всех элементов массива c[20].Каждый класс снабжается конструктором копирования по умолчанию.

Его имя (как и имялюбого другого конструктора) совпадает с именем класса, при этом он имеет одинпараметр – константную ссылку на объект того же класса. Например, для класса Vectorконструктор копирования имеет следующий прототип:Vector(const Vector &);8. Динамическое распределение памяти в классеПредположим мы хотим добавить в класс Vector элемент данных для хранения именивектора. В принципе, для этого подошло бы поле char c[100]. Однако хранить в каждомновом объекте массив из 100 элементов довольно расточительно, если в большинствеслучаев длина имени гораздо меньше. Возможно, лучшим решением будет динамическоевыделение необходимой памяти при создании объекта.

При этом в классе объявляетсяуказатель:class Vector{private:double x;double y;char *c;…}Непосредственно память удобно выделить объекту с помощью оператора new[] в моментего создания, т.е. при вызове конструктора. Например, класс Vector можно снабдитьконструктором с тремя параметрами, последним из которых будет указатель на строку сименем вектора:Vector::Vector(double xx, double yy, const char *str){x = xx;y = yy;int len = strlen (str)+1;cp = new char[len];strncpy(cp, str, len);}4Для освобождения выделенной оператором new [] объекту дополнительной памятиследует использовать деструктор:Vector::~Vector(){delete [] cp;}Проблемы при таком подходе могут возникнуть с конструктором копирования иоператором присваивания по умолчанию. При их использовании будет скопированозначение указателя cp, но не сама дополнительная память.

Это приведет к тому, что дваобъекта будут иметь два разных (у каждого свой) указателя, которые указывают на одну итуже область памяти. Это является источником потенциальных ошибок. Например, приудалении одного объекта, указатель в другом объекте будет указывать на уженесуществующую область памяти. Чтобы этого избежать, при копировании (иприсваивании) нужно копировать не указатели, а сами данные (эта процедура называется«глубоким копированием»), выделяя новую область памяти для их хранения.Для этого нужно перегрузить конструктор копирования класса:Vector::Vector(const Vector & v2){x = v2.x;y = v2.y;int len = strlen (v2.cp)+1;cp = new char[len];strncpy(cp, v2.cp, len);}В нем обычные элементы данных по-прежнему просто копируются, а для динамическихданных вначале выделяется новое место, куда и происходит затем копирование.По этой же причине следует переопределить и оператор присваивания, которыйдолжен вначале удалить выделенную ранее область памяти, затем выделить новуюобласть необходимого размера и скопировать туда значения динамических элементовданных:Vector::Vector & operator=(const Vector & v){if (this == &v) return *this;delete [] cp;x = v.x;y = v.y;int len = strlen(v.cp)+1;cp = new char[len];strncpy(cp, v.cp, len);return *this;}Условный оператор здесь использован для обработки случая, когда присваиваниепроисходит самому себе: v = v.Такой подход предполагает, что при создании объекта в каждом конструкторе выделяетсядинамическая память.

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

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

Тип файла PDF

PDF-формат наиболее широко используется для просмотра любого типа файлов на любом устройстве. В него можно сохранить документ, таблицы, презентацию, текст, чертежи, вычисления, графики и всё остальное, что можно показать на экране любого устройства. Именно его лучше всего использовать для печати.

Например, если Вам нужно распечатать чертёж из автокада, Вы сохраните чертёж на флешку, но будет ли автокад в пункте печати? А если будет, то нужная версия с нужными библиотеками? Именно для этого и нужен формат PDF - в нём точно будет показано верно вне зависимости от того, в какой программе создали PDF-файл и есть ли нужная программа для его просмотра.

Список файлов семинаров

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