- •Предисловие
- •Введение
- •Введение в программирование
- •1.1. Предисловие к курсу
- •1.2. Идеология языка
- •1.3. Обзор среды Microsoft Developer Studio
- •1.4. Жизненный цикл программного обеспечения
- •1.5. Общая структура программы
- •1.6. Директивы препроцессора
- •1.7. Построение исполняемого файла
- •1.8. Строительные блоки программы
- •Контрольные вопросы
- •Типы данных. Переменные. Массивы. Операции и Указатели
- •Стандартные типы и размеры данных
- •2.1.1. Объявление переменных
- •Управляющие символьные константы
- •2.2. Объявление указателя
- •2.2.1. Операции разыменования и взятия адреса
- •2.2.2. Указатели на указатели
- •2.2.3. Арифметические операции с указателями
- •2.3. Массивы
- •2.3.1. Инициализация массивов
- •2.3.2 Динамические массивы
- •2.3.3. Методы доступа к элементам массивов
- •2.3.4. Массивы указателей
- •2.4. Строки
- •2.5. Операции
- •2.5.1. Арифметические операции
- •Арифметические операции
- •2.5.2 Операции сравнения и логические операции
- •Операции сравнения и логические операции
- •2.5.3. Побитовые операции
- •Побитовые операции
- •Контрольные вопросы
- •3.1. Базовые операторы
- •3.1.1. Оператор выражение
- •3.2.2. Оператор switch
- •3.3.4. Оператор goto
- •3.4. Операторы цикла
- •3.4.1. Оператор for
- •3.4.2. Оператор while
- •3.4.3. Оператор do..While
- •Контрольные вопросы
- •Стандартный ввод/вывод. Работа с файлами.
- •4.1. Роль стандартного ввода/вывода
- •4.1.1. Основные функции стандартного ввода/вывода
- •4.2. Понятие файла
- •4.2.1. Строение файлов
- •4.2.2. Порядок работы с файлом
- •4.2.3. Обзор библиотечных функций с для работы с файлами
- •4.3. Программные конструкции при работе с файлами
- •4.3.1. Открытие/закрытие файла
- •4.3.2. Цикл посимвольного чтения содержимого файла
- •4.3.3. Цикл построчного чтения содержимого файла
- •Контрольные вопросы
- •Функция. Пользовательские типы данных.
- •5.1. Понятие функции
- •5.1.1. Определение функции
- •5.1.2. Формальные параметры
- •5.1.3. Тип возвращаемого значения
- •5.1.4. Тело функции
- •5.1.5. Фактические параметры
- •5.1.6. Рекурсивные вызовы
- •5.1.7. Передача параметров
- •5.1.8. Библиотеки стандартных функций
- •5.2. Пользовательские типы данных.
- •5.2.1. Ключевое слово typedef
- •5.2.2. Перечислимый тип данных
- •5.2.3. Понятие структуры
- •5.2.4. Указатели на структурный объект
- •Контрольные вопросы
- •Работа с динамической памятью. Динамические структуры данных
- •6.1. Работа с динамической памятью
- •6.1.1. Статическое и динамическое распределение памяти
- •6.1.2. Основные принципы динамического распределения
- •6.1.3. Способы работы с динамической памятью
- •6.2. Динамические структуры данных
- •6.2.1. Стек
- •6.2.2.Линейный список
- •Контрольные вопросы
- •Объектно-ориентированное программирование
- •7.1. Критерии качества декомпозиции проекта
- •7.2. Новые концепции программирования
- •7.3. Достоинства ооп
- •7.4. Объекты и классы в ооп
- •7.4.1. Определение класса
- •7.4.2. Использование класса
- •7.4.3. Вложенные классы
- •Контрольные вопросы
- •Конструкторы и Перегрузка операций.
- •8.1. Перегрузка операций
- •8.1.1. Перегрузка операций внешними функциями
- •8.1.2. Перегрузка операций методами класса
- •8.2. Конструкторы и деструктор
- •8.2.1. Конструкторы и параметры
- •Контрольные вопросы
- •9.1. Простое открытое наследование
- •9.1.1 Конструкторы и деструкторы при наследовании
- •9.1.2. Поля и методы при наследовании
- •9.1.3. Вложенные классы и наследование
- •9.1.4. Закрытое наследование
- •9.1.5. Виртуальные функции
- •9.1.6. Чистые виртуальные функции и абстрактные классы
- •9.3. Основы программирования под Windows
- •9.3.1. Типы данных в Windows
- •9.4. Cреда Microsoft Developer Studio
- •9.4.1. Библиотека mfc
- •9.4.2. Архитектура приложения
- •9.4.3. Каркас приложения
- •9.4.4. Проект приложения
- •Контрольные вопросы
- •Заключение
- •Список Литературы
Конструкторы и Перегрузка операций.
8.1. Перегрузка операций
В C++ разрешено перегружать встроенные операции – это одно из проявлений полиморфизма. Перегрузка операций не является обязательной в ООП – в языках Java и С# она отсутствует. Однако наличие перегрузки операций в C++ обеспечивает дополнительный уровень удобства при использовании новых типов данных.
При программировании нового типа данных желательно объявлять объекты нового типа аналогично встроенным – формы инициализации не должны отличаться от форм инициализации объектов встроенного типа. Эти возможности обеспечивают конструкторы.
При перегрузке операции нужно учитывать следующие ограничения.
1. Запрещена перегрузка следующих операций:
- sizeof() – определение размера аргумента;
- . (точка) – селектор компонента объекта;
- ?: – условная операция;
- :: – указание области видимости;
- .* – выбор компонента класса через указатель;
- # и ## – операции препроцессора.
2. Операции можно перегружать только для нового типа данных – нельзя перегрузить операцию для встроенного типа. В C++ новый тип данных можно образовать с помощью конструкций enum, union, struct и class.
3. Нельзя изменить приоритет перегружаемой операции и количество операндов. Унарная операция обязана иметь один операнд, бинарная – два операнда; не разрешается использовать параметры по умолчанию. Единственная операция, которая не имеет фиксированного количества операндов, – это операция вызова функции (). Операции «+», «-», «*», «&» допускается перегружать и как унарные, и как бинарные.
4. Операции можно перегружать либо как независимые внешние функции (только такой способ перегрузки допустим для enum), либо как методы класса. Четыре операции:
- присваивания =;
- вызова функции ();
- индексирования [];
- доступа по указателю ->;
- допускается перегружать только как методы класса. Эти операции в принципе нельзя перегрузить для конструкции enum.
5. Если операция перегружается как метод класса, то левым (или единственным) аргументом обязательно будет объект класса, для которого перегружается операция.
Прототип функции-операции выглядит следующим образом:
тип operator@(список параметров);
где @ – символ операции. Слово operator является зарезервированным словом и может использоваться только в определении или в функциональной форме вызова операции.
8.1.1. Перегрузка операций внешними функциями
Прототип бинарной операции, перегружаемой как внешняя независимая функция, выглядит так:
тип operator@(параметр_1, параметр_2);
Для обеспечения коммутативности бинарной операции с параметрами разного типа, как правило, требуется реализовать две функции-операции:
тип operator@(параметр_1, параметр_2);
тип operator@(параметр_2. параметр_1);
Хотя бы один из параметров должен быть нового типа. Параметры можно передавать любым допустимым способом. Обращение к операции выполняется двумя способами:
- инфиксная форма параметр_1 @ параметр 2;
- функциональная форма operator@ (параметр_1, параметр2).
Прототип унарной операции, перегружаемой независимой внешней функцией, отличается только количеством параметров:
тип operator@(параметр);
Параметр должен быть нового типа. Обращаться к перегруженной операции следует так:
- инфиксная форма @параметр;
- функциональная форма operator@(параметр).
Операции инкремента ++ и декремента -- имеют две формы: префиксную и постфиксную. В определении постфиксной формы операции должен быть объявлен дополнительный параметр типа int.
тип operator@(параметр, int);
Этот параметр не должен использоваться в теле функции. Инфиксная форма обращения к такой операции – параметр@; при функциональной форме обращения необходимо задавать второй фиктивный аргумент, например: operator@(параметр,0);
В следующем листинге программы приведен пример перегрузки операций для перечислимого типа.
enum Week { mon = 1, tue, wed, thu, fri, sat. sun = 0 };
Week operator+(const Week &m, const int &b)
{ Week t = Week(b + m);
return (t = Week(t%7));
}
// вторая функция для коммутативности сложения
Week operator+(const int &b, const Week &m)
{ return (m+b); }
Week operator++(Week &m) // префиксная форма
{ return (m = Week(m+l)); }
Week operator++(Week &m, int) // постфиксная форма
{ Week t = m; m = Week(m+l); return t; }
void print(const Week &d) //вывод на экран названий дней недели
{ string Days[7] = {"Sunday", "Monday", "Tuesday".
"Wednesday", "Thursday", "Friday", "Saturday"
};
cout << Days[d] << endl;
};
Week m = sat: // m = суббота
print(m+l); // выводит 'Sunday'
print(2+m); // выводит 'Monday'
print(operator+(m.D); // выводит 'Sunday'
print(operator+(2.m)); // выводит 'Monday'
m++; // вызов постфиксной формы, m == sun
print(m); // выводит 'Sunday'
print(++m); // выводит 'Monday'
print(operator++(m)); // префиксная форма, выводит 'Tuesday'
print(operator++(m,0)); // постфиксная форма, выводит 'Tuesday'
print(m); // выводит 'Wednesday'
При перегрузке операции внешней для класса функцией поля должны быть открыты или класс должен предоставлять методы get О и set О для получения и изменения значений полей.
Пример перегрузки операции внешней функцией для класса показан в следующем листинге программы.
struct Fraction
{ int num; int denum; // поля - открыты
void reduce (); // метод - открыт
};
Fraction operator+(const Fraction &l. const Fraction &r)
{ Fraction t;
// (a.b)+(c,d)=(ad+bc.bd)
t.denum = l.denum*r.denum; // знаменатель результата
t.num = 1.num*r.denum+r.num*l.denum; // числитель результата
t.reduce(): // сокращение
return t:
}
Fraction a, b, c;
// ...
a = b + с; // инфиксная форма
a - operator+(b.c); // функциональная форма