Лекции по СП, страница 3

2019-05-09СтудИзба

Описание файла

Документ из архива "Лекции по СП", который расположен в категории "". Всё это находится в предмете "практикум (прикладное программное обеспечение и системы программирования)" из 4 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "Лекции по СП"

Текст 3 страницы из документа "Лекции по СП"

Complex x (1.5); // x = 1.5

Complex y; // y = 0

const Complex t (5); // t – константа 5

Complex z1 = z; // конструктор копирования

Complex z2 = Complex (1,2); // создаётся временный об’ект

//Complex (1,2), потом вызывается конструктор копирования

// компиляторы часто оптимизируют и не создают вр. об’ект

// (стандартом это допускается; в то же время доступность

// конструктора копирования все равно проверяется)

z2 = z; // оператор присваивания

z = t; // для этого пишем const в параметре констр. копир-я

z2.operator= (t); // то же самое

Complex *p;

p = new Complex (1.5); // отводится память в куче

// и вызывается конструктор

/* работа с p */

delete p; // вызывается деструктор, память возвр. в кучу

Complex p[10]; // по адресу p выделяется память для 10

//об’ектов типа Complex. Работает конструктор умолчания

// если он не определён, ошибка!

//инициализировать массив конструкторами с параметрами,

// к сожалению, нельзя 

return 0;

}



Особенности работы с неплоскими классами.

Пример. Описание класса MFC-строк.

class String { // С-шная строка, с которой хранится её длина.

int size; // длина строки без ‘\0’

char *p; // указатель на строку

public:

String (const char *str){ // конструктор

p = new char [(size = strlen(str)) + 1];

strcpy (p, str);

} // теперь можно создавать строки: String a (“Hello!”);

~String () { delete[] p;}

Пусть теперь с классом работает некоторая функция:

void f(){

String s1 (“Hello!”);

String s2 = s1;

String s3 = String (“2007”);

s3 = s1;

}

Тут происходит поверхностное копирование конструкторами по умолчанию. Это значит, что копируются указатели, но не содержание строк. В этой ситуации s1.p и s2.p ссылаются на одну и ту же область памяти, а при присваивании в последней строчке мы оставляем в памяти мусор. Но самое интересное начнётся при выходе из функции, когда начнёт работать описанный нами деструктор. Он захочет три раза удалить память, занятую строчкой “Hello!”. Но двум смертям не бывать, получим runtime error.

Напишем специальные функции, поддерживающие глубинное копирование.

String (const String &a){

p = new char [(size = a.size) + 1];

strcpy (p, a.p);}

String& operator= (const String &a){

if (this == &a) return *this; // если s1 == s2

delete[] p; // освобождаем память для старой строки

p = new char [(size = a.size) + 1];

strcpy (p, a.p);

return *this;}



Абстрактные типы данных. Перегрузка операций.

Абстрактный тип данных (АТД) — это такой тип, который предоставляет для работы с элементами этого типа определённый набор функций, а также возможность создавать элементы этого типа при помощи специальных функций. Вся внутренняя структура такого типа спрятана от разработчика программного обеспечения — в этом и заключается суть абстракции. Абстрактный тип данных определяет набор независимых от конкретной реализации типа функций для оперирования его значениями. Например, можно определить абстрактные типы для стека, очереди, списка.

Перегрузка операций – описание своих операций (+, -, new и т.д.) вместо уже определённых.

Нельзя перегружать операции: ., ?:,::, .* , # , ## , sizeof, typeid.

Если мы перегружаем какой-нибудь значок, надо стараться, чтобы он определял похожую на обычный вкладываемый в него смысл сущность. Например, разумно использовать * для перемножения матриц или многочленов или для кон’юнкции.

К сожалению, мы не можем изменить арность операций, то есть бинарная операция всегда будет бинарной, а унарная – унарной. Также операции будут подчиняться законам старшинства, определённым раньше. Часто программисты сталкиваются с проблемой при перегрузке оператора ^ в качестве возведения в степень. От побитового сложения по модулю 2 нам достался приоритет, меньший, чем у сложения или умножения. Очевидно, это противоречит вкладываемому в него смыслу, и приходится использовать скобки.



Перегрузка бинарных операций.

Существует три возможности перегрузки операций:

1) написать функцию-член класса с одним параметром;

2) с помощью глобальной функции с двумя параметрами (в этом случае нам нужен доступ к скрытым полям класса с помощью сеттеров/геттеров, но так получается медленнее и вообще не используется);

3) функция-друг класса с двумя параметрами (если класс об’являет функцию своим другом, она может использовать все поля класса).

Пример. Продолжение описания класса комплексных чисел.

const Complex operator+ (const Complex &a) const{

Complex t (re + a.re, im + a.im);

return t;}

При использовании z = x + y, x – вызывающий об’ект, а y – параметр. Можно опустить const у параметра, но тогда нельзя будет складывать об’екты нашего класса с константами, то есть z = y + 5.

Почему мы возвращаем значение не по ссылке? Если бы мы действительно сделали так, мы вернули бы адрес локальной переменной, которая лежит в стеке, и её память освобождается после выхода из функции. Конечно, можно рассчитывать на то, что компилятор не заругается (зависит от реализации), и значение t не успеет затереться, просто переместится указатель стека. Но тогда, если мы напишем цепочку сложений, то при следующем вызове функции об’ект t скорее всего будет создан на том же месте, и тогда точно программа полетит. Не возвращайте локальные переменные по ссылке!

lvalue – переменная, которой возможно присваивание (она обладает адресом).

rvalue – кусок памяти, которому нельзя присваивать, например, константа или временный результат вычисления.

Самый первый const превращает полученный результат из lvalue в rvalue. Иначе можно будет вызвать, например (a+b).change(1), а это не по-C++ному.

int main (){

double t = 7.5;

Complex x(1,2), y(5), w;

const Complex z(1,3);

w = x + y; // равносильно w = x.operator+(y);

// или w.operator= (x.operator+(y));

w = x + z; // можно из-за const у параметра

w = z + x; // можно из-за const в конце

w = x + t; // преобразование типа double к const Complex

// w = x.operator+ (Complex(t)); т.к. есть Complex(double)

w = t + x; // ашыпка

return 0;}

Теперь рассмотрим перегрузку с помощью дружественной функции. Для этого в классе нужно написать:

friend const Complex operator+ (const Complex &a, const Complex &b);

Зона видимости функции совпадает с областью видимости класса. private: на неё не действует! Описание в классе или вне класса (тот же профиль без friend) приводит к одинаковому результату.

const Complex operator+ (const Complex &a, const Complex &b){

Complex t (a.re + b.re, a.im + b.im);

return t;}



int main(){

double t = 7.5;

Complex x(1,2), y(3), z;

z = x + y; // z = operator+ (x, y);

z = x + t; // z = operator+ (x, Complex(t));

z = t + x; // z = operator+ (t, Complex(x));

return 0;}

Так что, если мы хотим смешивать данные, лучше заводить друзей. ;)

Формально можно перегрузить оператор и в классе, и с помощью друга.

z = x + y; // неоднозначность - ошибка

z = x + t; // неоднозначность - ошибка

z = t + x; // друг работает



Перегрузка унарных операций.

Есть те же три возможности перегрузить унарный оператор (функция-член класса без параметров, обычная глобальная функция или функция-друг с 1 параметром).

const Complex operator- () const{

Complex t (-re,-im); return t;}



int main (){

double t = 7.5;

Complex x(1,2), y;

const Complex z (1);

y = -x; // y = x.operator-();

y = -z; // y = z.operator-();

-x = y; // низя, т.к. –x не l-value

x = -t; // x = Complex (-t); - здесь нет нашего отрицания

return 0;}

Друга пишут аналогично прошлому разу.



Особенности перегрузки операций ++ и --.

Как обычно, есть 3 варианта.

Чтобы отличать описание префиксной формы от описания постфиксной, договорились, что функция для префиксной формы описывается без формальных параметров, а для постфиксной – с одним параметром типа int.

const Complex& operator++ () // ++x;

{ ++re; ++im; return *this;}



const Complex operator++ (int notused) // x++;

{Complex t = *this;

++re; ++im;

return t;}



int main () {

Complex x(1,2); y;

y = ++x; // y = x.operator++();

y = x++; //y = x.operator++(0); -обычно там реально ноль

++ ++x; // нельзя, т.к. ++x не l-value

y = (x + y)++; // нельзя, так мы определили сложение

return 0;}

Еще одно глобальное замечание: совершенно не обязательно при перегрузке, скажем, бинарной операции функцией-членом класса делать тип операнда совпадающим с типом неявного.



Виды отношений между классами.

Выделяют следующие темы межклассовых отношений:

  • ассоциация

  • наследование

  • агрегация

  • использование

  • инстанцирование (выделяют не всегда)

Ассоциация – тот факт, что пара об’ектов связана между собой. Связь не конкретизируется, обычно такая связь появляется в начале планирования, а потом уточняется и переходит в другие формы.

Далее будем приводить UML-подобные примеры, точнее, мы будем рисовать ER-диаграммы (Entity Relations), которые пришли из области баз данных.

Степень связи (мощность) показывает, сколько об’ектов с каждой стороны могут участвовать в связи. Обозначается спецификацией около карточки.

Возможные виды связей:

  • один к одному

  • один ко многим

  • многие ко многим

Наследование – взаимодействие, выражающее связь ‘частное - общее’ (‘is a‘), например, любое млекопитающее есть животное.

Общее считается базовым классом, а частное – производным. В другой терминологии, принятой, например, в Java, это суперкласс и подкласс. На диаграммах стрелочки рисуются от производного класса к базовому. Производный класс может расширить базовый класс, а может переопределить некоторые его члены.

Агрегация – соотношение ‘часть - целое’ (‘has a’) – ситуация, при которой об’ект одного класса внутри себя содержит об’екты другого класса.

Различают строгую и нестрогую агрегацию. Строгая агрегация (композиция) – агрегация, при которой вложенный об’ект не может исчезнуть, пока существует его хозяин. Тогда ромбик на диаграмме закрашивают.

class Triangle { ... Point v1, v2, v3; ... }

Нестрогая агрегация (часто просто агрегация) – часть может исчезнуть, пока существует целое, например, у треугольника можно отрезать вершину.  Тогда ромбик не закрашивают.

class Shareholder { ... Share *asserts; ... }

Возможно, share == NULL. Вот такой у нас безNULL. 

Использование (зависимость) возникает в трёх случаях:

  • ситуация, при которой имя класса используется в профиле функции-члена другого класса (тип параметров или возвращаемого значения);

  • функция-член одного класса для реализации использует локальную переменную типа – другого класса;

  • в теле функции-члена одного класса вызывается функция-член другого класса, то есть, либо у нас есть статическая функция, либо мы поступаем, как в предыдущем пункте.

При этом используемый класс называется сервером, использующий – клиентом.

Инстанцирование – получение из некоторого абстрактного типа конкретного, из которого потом генерируются об’екты, то есть это связь шаблона класса и того, что генерируется по шаблону.



Единичное наследование в C++

Теперь можно рассказать о модификаторе доступа protected. Если имена попали в эту секцию, это значит, что вне класса они не видимы, так же, как private, однако они доступны в производных классах.

Пример. Сотрудники.

class Person { // человек

protected:

char *name;

int age;

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