МУ_ДЗ_2014 (Методические указания к лабораторным работам), страница 3

2018-01-11СтудИзба

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

Файл "МУ_ДЗ_2014" внутри архива находится в папке "Методические указания к лабораторным работам". Документ из архива "Методические указания к лабораторным работам", который расположен в категории "". Всё это находится в предмете "программирование на основе классов и шаблонов" из 2 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "книги и методические указания", в предмете "программирование на основе классов и шаблонов" в общих файлах.

Онлайн просмотр документа "МУ_ДЗ_2014"

Текст 3 страницы из документа "МУ_ДЗ_2014"

Здесь терминальная переменная <ФП> - это имя формального параметра, его упускать нельзя. Остальные правила задания параметров по-умолчанию сходны. Пример:

int Summa( int a = 10 , int b = 20 , int c = 30) // Три параметра по умолчанию.

{

return ( a + b + c ); };

Для такой функции также допустимы следующие четыре вызова, в зависимости от числа параметров взятых по-умолчанию:

cout << "Сумма = "<< dec << Summa1 ( ) <<endl;

cout << "Сумма = "<< Summa( 3 ) <<endl;

cout << "Сумма = "<< Summa(3 , 3) <<endl;

cout << "Сумма = "<< Summa(3 , 3 , 3 ) <<endl;

Рассмотрим использование глобальных переменных для задания начальных значений:

int iGlob = 5; // Глобальная переменная

// …

int Summa( int a = 10 , int b = 20 , int c = iGlob)

{ return ( a + b + c ); };

Вызов функции с предварительным изменением глобальной переменной:

cout << "Сумма = "<< Summa1 (3 , 3) <<endl;

iGlob = 15;

cout << "Сумма = "<< Summa(3 , 3) <<endl; // Третий фактический параметр = 15

Глобальная переменная должна быть описана перед описанием прототипа или определения функции, то есть находиться в области видимости.

19 Перегрузка функций (Статическое связывание)

Перегрузка функций заключается в возможности вызывать функции с одинаковыми именами, но для разных типов параметров, точнее функций с разной сигнатурой. Уменьшение числа разнообразных имен для разных типов объектов значительно увеличивает степень понятности, читаемости и наглядности программ. Сравните варианты названий для функции перемещения разных объектов (Move – при перегрузке можно использовать одно имя): MoveRect, MoveLine, MovePoint и т.д. Число таких названий функций в программе может быть большим. При использовании механизма перегрузки мы можем воспользоваться одним именем Move для объектов разных типов, в этом случае не надо помнить различные имена!

Поясню, что понимается под сигнатурой функции. Это понятие не просто определить одним предложением. В сигнатуру функции входит:

  • Название (имя) функции,

  • Определения типов параметров.

  • Число параметров.

  • Тип данных возврата функции.

  • Вариант последовательности (порядка) типов параметров.

Функции, которые имеют разные имена, имеют разную сигнатуру. Функции, которые имеют разное число фактических параметров, будут иметь разную сигнатуру. Функции, в которых параметры по типам и номерам не совпадают, имеют разную сигнатуру. Правило перегрузки функций звучит так: если функции имеют разную сигнатуру, исключая имя функции, то их можно описывать и использовать повторно. Другими словами, можно использовать функции с одинаковыми именами для разных совокупностей формальных параметров. Рассмотрим пример для функции Swap, применительно к ссылкам и указателям. Описание функций:

void Swap(int * x , int * y) // Указатели

{ int Temp = *x;

*x=*y;

*y=Temp;};

//

void Swap(int & x , int & y) // ссылки

{ int Temp = x;

x=y;

y=Temp;};

При вызове функции с параметрами указателями, будет вызвана 1-я функция:

int x = 5, y = 10;

Swap (&x , &y);

При вызове функции с параметрами ссылками, будет вызвана 2-я функция:

Swap (x , y);

Если в программе есть описание другой функции Swap с другими типами, например типом float для ссылок:

void Swap(float & x , float & y) // ссылки

{ float Temp = x;

x=y;

y=Temp;};

То ее можно вызвать, задавая параметры других типов (float):

float x = 5, y = 10;

Swap (x , y);

На этапе компиляции (статическое связывание) компилятором определяется описание функции, которое будет использоваться в каждом конкретном случае. Вспомним из предыдущих ЛР, что для этого случая целесообразнее использовать шаблоны функции, когда число параметров совпадает (Напомним, что шаблон функции позволяет компилятору фактически сгенерировать описание перегруженных функций и одинаковыми алгоритмами). Если число параметров не совпадает, то перегрузка функций незаменима, например:

int Summa( int a , int b , int c ) // Три параметра

{

return ( a + b + c ); };

int Summa( int a , int b ) // Два параметра

{

return ( a + b ); };

Тогда при вызове описанных выше функций таким образом:

// Число параметров при перегрузке

cout << "Сумма = "<< Summ (3 , 3 , 3 ) <<endl; // Вызов первой функции

cout << "Сумма = "<< Summ (3 , 3) <<endl; // Вызов второй функции

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

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

20 Суть механизма перегрузки операций

Механизм перегрузки операций в языках ООП позволяет задать для новых типов объектов новый смысл (порядок, алгоритм) выполнения стандартных операций. Например, для объектов типа строка можно записать:

String S1("Первая ");

String S2("Вторая ");

String S3();

S3 = S1 + S2;

Такая запись является наглядной и компактной (сравните с вариантом вызова функции RTL - strcat). Алгоритмы выполнения перегруженных операций могут быть любыми, так как они реализуются через функцию, которую описывает сам программист. Можно придумать самые разнообразные операции (даже фантастические) и реализовать в своей программе. Например, сложение двух улиц, домов и т.д (см. пособие[6]). Для потокового ввода/вывода, например, перегружены стандартные операции двоичного сдвига: “>>” и “<<”.

Повторю в итоге еще раз: перегрузка операцийэто задание новых способов выполнения операций для новых типов объектов.

21 Ограничения перегрузки операций

В языке С++ не все стандартные операции можно перегружать, есть ограничения. Это обуславливается особенностями синтаксиса языка и конструкцией компилятора. Так запрещено перегружать следующие операции:

  • Операцию разрешения области видимости – “::

  • Условную операцию – “() ? :

  • Операцию доступа к членам класса через объект и указатель на член класса– “*.

  • Операцию разрешения квалифицированной ссылки “.

Все остальные операции, включая и операцию индексирования (“[]”) можно перегружать. Использование приемов перегрузки операций позволяет сделать программный проект на основе классов более наглядным и качественным.

Для задания типа операции может использоваться один символ (знак) или два символа (знака). Так для бинарной операции сложения – один знак “+”, а для операции инкремента – два знака “++”. При перегрузке операций нужно это учитывать. Перегрузка операций выполняется в классах в виде функций класса или функций дружественных данному классу. Перегрузка операций для стандартных типов переменных не допускается. Рассмотрим разновидности перегрузки операций.

22 Разновидности типов перегрузки операций

Перегрузка операций имеет несколько разновидностей. В зависимости от числа операндов (значений, участвующих в операции), они подразделяются на одноместные и двуместные. Одноместная операция выполняется над одним операндом, например вывод переменной в поток (”<<”). Для выполнения двуместной операции необходимо два однородных (одного типа) операнда, например сложение двух строк (”+”). В некоторых операциях, например, индексирования указываются два разнородных операнда: тип контейнерного объекта и номер элемента в объекте.

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

  • Внутренняя одноместная перегрузка операций (без параметров)

  • Внутренняя двуместная перегрузка операций (нужен один параметр)

  • Внешняя одноместная перегрузка операций (нужен один параметр)

  • Внешняя двуместная перегрузка операций (нужны два параметра)

23 Формальное описание перегруженной операции

Формальное описание заголовка перегруженной функции-операции выглядит так:

<тип возврата> operator <знаки операции>(<список формальных параметров> )

{<тело функции>};

Знаки операции это любая доступная стандартная операция (“+”, “-” и т.д.), кроме исключений перечисленных выше. Тип возврата определяет тип результата, который должен быть возвращен при выполнении операции. Чаще всего это тип объекта (точнее ссылка на тип объекта), который участвует в операции и для которого перегружается данная операция. Список формальных параметров и тело функции соответствуют обычному описанию функции. Служебное слово operator указывает на то, что выполняется описание перегруженной операции. Пример описания операций с разным числом параметров:

String operator + (String & s) {}; // Перегрузка операции прибавления строки

Test operator ++ () {}; // Перегрузка операции инкремента (без параметров)

friend String operator + (String & s1 , String & s1){};// Перегрузка операции сложения строк

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

24 Внутренняя одноместная перегрузка операций

Для описания внутренней одноместной перегрузки операций используется метод без формальных параметров. Пусть у нас есть класс Test, отвлечемся от его содержания и назначения. Для тестового класса зададим следующее описание:

class Test {

public:

int Num; // Переменная целого типа

Test(){ Num = 0; }; // Конструктор без параметров

Test(int i){ Num = i; }; // Конструктор с параметром

… };

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

Test & operator ++() {Num++; return *this; };

Для операции декремента можно описать вне описания класса следующую перегруженную операцию (при описании вне класса указание имени Test:: области видимости нового оператора обязательно):

Test & Test::operator --() {--Num; return *this; };

Примечание. Перегрузка одноместных операций может быть префиксной и постфиксной. В этом случае для постфиксной перегрузке в описание функции добавляется специальный параметр целого типа (int). Подробнее смотри в [1]. Эти вопросы нужно самостоятельно учить в литературе [1].

При этом в классе должен быть обязательно задан прототип перегруженного декремента:

Test & operator --(); // Прототип в описании класса

Тогда в основной программе мы можем проверить использование наших перегруженных одноместных операций:

Test a2(5);

cout << "++a2 = "<< ++a2 <<endl; // справедлива постфиксная записи

cout << "a2++ = "<< a2++ <<endl; // справедлива запись после переменной

cout << "--a2 = "<< --a2 <<endl;

Результат работы программы , полученный на консоли, выглядит так:

++a2 = 6

a2++ = 7

--a2 = 6

25 Внутренняя двуместная перегрузка операций

При описании внутренней двуместной операции необходимо указать один параметр, указывающий на второй операнд. Первый операнд двуместной операции задается объектом класса (указатель - this), для которого вызвана функция - операция. Для нашего простого класса можем описать следующий метод операции “+” , описанный внутри класса:

Test operator +(Test & X )

{ Test T;

T.Num = this->Num + X.Num ;

return T; };

Или метод, описанный вне класса:

Test2 & Test2::operator -(Test2 & X) {

Test2 T;

T.Num = this->Num - X.Num ;

return T; };

В самом же классе опишем прототип операции “-”:

Test2 & operator - (Test2 & X);

Тогда в основной программе мы можем проверить использование определенных выше перегруженных двуместных операций:

Test a2(5) , b2(3), c2;

c2 = a2 + b2;

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