- •Предисловие
- •Введение
- •Введение в программирование
- •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.2. Перегрузка операций методами класса
У методов один параметр – текущий объект – определен по умолчанию. Унарные операции выполняются для текущего объекта, который и является единственным аргументом. Поэтому унарные операции, перегружаемые как методы класса, не имеют параметров. Прототип унарной операции, реализованной как метод класса, выглядит так:
тип operator@();
где @ – символ операции. Возвращаемое значение может быть любого типа, в том числе и определяемого класса. Операция может возвращать значение, ссылку или указатель на объект. Разрешается указывать void на месте типа возвращаемого значения.
Постфиксные операции инкремента и декремента являются исключением из этого правила. Чтобы отличить постфиксную операцию от префиксной, в постфиксной форме задается фиктивный параметр типа int, который реально не используется.
Префиксная форма инкремента (и декремента) должна иметь прототип:
тип& operator@();
Постфиксная операция инкремента (и декремента) должна иметь прототип:
тип operator@(int);
Тип – это «имя_класса», в котором определяется операция.
Прототип бинарной операции имеет один аргумент и выглядит таким образом:
тип operator@(параметр);
Параметры разрешается передавать любым удобным нам способом: по значению, по ссылке или по указателю. Возвращать метод-операция тоже может значение, указатель или ссылку на объект, в том числе и своего класса. Разрешается указывать void на месте типа возвращаемого значения.
При реализации метода-операции вне класса требуется в заголовке обычным образом указывать префикс-имя класса:
тип класс::operator@() // унарная операция
тип класс::operator@(параметр) // бинарная операция
Вызов унарной операции для объекта имеет форму;
@объект;
объект@;
в зависимости от того, какой вид операции используется – префиксный или постфиксный. Функциональный вызов для префиксной операции имеет форму:
объект.operator@()
Для постфиксной операции в функциональной форме вызова нужно задавать фиктивный аргумент:
объект.operator@(0)
Функциональная форма вызова для бинарной операции, определенной как метод класса, выглядит так:
объект.operator@(аргумент)
Операции присваивания являются бинарными операциями, поэтому должны иметь один аргумент. Если операция присваивания operator= не реализуется явным образом, она создается автоматически по умолчанию. Для любого класса автоматически создаваемая операция присваивания имеет прототип:
класс& operator=(const класс &r)
Допускается реализовать операцию присваивания с параметром и возвращаемым результатом не своего класса; разрешается передавать параметр любым способом; возвращать можно не ссылку, а значение или указатель – все зависит от потребностей задачи.
Другие операции с присваиванием автоматически не создаются. Функции-операции с присваиванием обычно должны возвращать ссылку на текущий объект. Любой метод, возвращающий неконстантную ссылку, можно использовать многократно:
Money& Money::operator+=(const Money &b)
Любая внешняя функция, определенная как «друг» класса, имеет неограниченный доступ к любым элементам класса, в том числе и к закрытым. Для того чтобы внешняя функция стала другом класса, необходимо в интерфейсе класса задать ее прототип, добавив впереди слово friend, например:
friend Money operator*(const long double &a, const Money &b);
При реализации функции слово friend писать запрещается. Не указывается также и префикс класса.
В частности, операции ввода/вывода operator>> и operator<< практически всегда реализуются как внешние дружественные функции. Например, для класса Two с двумя полями х и у целого типа эти функции могут выглядеть так:
ostream& operator<<(ostream& t, const Two &r)
{ return (t << '(' << r.x << '.' << r.y << ')'); }
istream& operator>>(istreams t, Two &r)
{ t >> r.x >> r.y; return t; }
Пример перегрузки операций методами класса и дружественными функциями показан в листинге следующем листинге программы.
class F
{ int f; int m;
public:
F(int t, int r = 0) // конструктор
{ f = t; m = г; }
F& operator++() // префиксный инкремент
{ f++; return *this; }
F operator++(int) // постфиксный инкремент
{ F t = *this; f++; return t; }
F& operator+=(const F& r) // сложение с присваиванием
{ f+=r.f; m+=r.m; return *this; }
// дружественные функции
friend F operator+(const F &1, const F &r);
friend ostream& operator<<(ostream& t. const F &r)
friend istream& operator>>(istreams t. F Sr)
};
// реализация дружественных функций
F operator+(const F &l, const F &r)
{ F t = 1; t+=r; return t; }
// дружественные функции ввода/вывода
ostream& operator<<(ostream& t, const F &r)
{ return (t << r.f << '/' << r.m); }
istream& operator>>(istreams t. F &r)
{ t >> r.f >> r.m; return t; } \