- •В.В. Чуркин технологии программирования
- •Содержание
- •Введение
- •Указатели. Операции над указателями Операции адресации и разыменования.
- •Арифметические операции.
- •Присваивание указателей.
- •Смещение и индексирование указателей.
- •Функции
- •Объявление функции (прототип)
- •Параметры функции
- •Встроенные функции
- •Функции с параметрами со значениями по умолчанию
- •Параметры функции main()
- •Рекурсивные функции
- •Перегрузка функций
- •Шаблоны функций
- •Указатели на функции
- •Объявление и инициализация массива указателей на функции:
- •Указатель на функцию как возвращаемое функцией значение
- •Выделение и освобождение динамической памяти
- •Символьные и строковые данные Символьные константы
- •Строковые константы (строки)
- •Символьные переменные
- •Строки – переменные
- •Специальные функции ввода-вывода строк
- •Стандартная библиотека функций языка с
- •Файлы Потоковый ввод-вывод в языке с Функции верхнего уровня файлового ввода-вывода
- •Открытие и закрытие потока
- •Текстовый режим
- •Бинарный режим
- •Закрытие файла
- •Функции в языке c для работы с файлами
- •Двоичный (бинарный) режим обмена с файлами
- •Строковый обмен с файлами
- •Форматный обмен с файлами
- •Позиционирование в потоке
- •Ввод-вывод нижнего уровня
- •Открытие / закрытие файла
- •Чтение и запись данных
- •Произвольный доступ к файлу
- •Позиционирование файлов
- •Сортировки числовых массивов Принцип наименьших привилегий
- •Обменная сортировка (SwapSort)
- •Сортировка выбором (SelectSort)
- •Пузырьковая сортировка (BubbleSort)
- •Сортировка вставками (InsertSort)
- •Быстрая сортировка (QuickSort)
- •Поиск в числовых массивах
- •Структуры
- •Форматы определения структурных типов
- •Форматы определения объектов структурных типов
- •Операции над объектами структурного типа
- •Доступ к элементам объектов структурного типа
- •Структуры, массивы и указатели
- •Объединения (смеси)
- •Оператор switch (переключатель)
- •Динамические структуры данных
- •Реализация стека с помощью массива
- •Очередь
- •Очередь приоритетов
- •Реализация очереди с помощью массива
- •Линейные списки
- •Функции для работы с двунаправленным линейным списком
- •Реализация списка с помощью массивов
- •Поиск хэшированием
- •Бинарные деревья
- •Бинарное упорядоченное дерево (дерево поиска)
- •Идеально сбалансированное дерево
- •Операции с бинарным упорядоченным деревом
- •Удаление узла из дерева
- •Обход (просмотр) дерева
- •Реализация дерева с помощью массивов
- •Вывод динамических структур в файл и чтение их из файла
- •Сбалансированные (avl) деревья
- •Алгоритм avl-вставки.
- •Повороты
- •Классы и объектно-ориентированное программирование
- •Объявление класса
- •Определение класса (реализация класса)
- •Использование класса (драйвер класса)
- •Доступ к элементам класса
- •Отделение интерфейса от реализации
- •Обслуживающие функции-утилиты
- •Конструкторы
- •Windows-программы в Builder
- •Структура головного файла проекта
- •Структура заголовочного файла модуля формы (“Unit1.H”)
- •Структура файла реализации модуля формы (“Unit1.Cpp”)
- •Области видимости (или области действия) переменных в блоках. Время жизни переменных
- •Доступ к свойствам и функциям-элементам (методам) объектов, переменным и функциям в приложении, содержащем одну форму
- •Константные объекты и константные функции-элементы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Перегрузка операции индексирования []
- •Дружественный класс
- •Использование указателя this
- •Композиция классов
- •Дружественные функции класса
- •Статические элементы класса
- •Шаблон класса для статически и динамически создаваемых объектов
- •Конструктор 1
- •Деструктор
- •Вызовы конструкторов и деструкторов
- •Перегруженная операция присваивания
- •Конструктор 2 (конструктор копирования, конструктор копии)
- •Наследование. Иерархия классов.
- •Ключи доступа
- •Пример простого наследования (точка, круг)
- •Правила наследования функций-элементов. Вызовы конструкторов и деструкторов в иерархии
- •Виртуальные функции и полиморфизм
- •Правила определения и наследования виртуальных функций
- •Позднее (динамическое) связывание
- •Полиморфизм. Абстрактные и конкретные классы
- •Учебная литература (основная)
- •Учебная литература (для углубленного изучения)
- •Учебно-методические издания
Константные объекты и константные функции-элементы
Пример объявления константного объекта:
const time noon(12,0,0); //полдень
Случайные попытки изменить константный объект отлавливаются во время компиляции и не вызывают ошибок во время выполнения.
Компиляторы не допускают никаких вызовов функций-элементов константных объектов. Поэтому объявляют константные функции-элементы, которые не могут изменить объект.
class time {
public:
time(int=0, int=0, int=0);
void settime(int, int, int);
void seth(int);
void setm(int);
void sets(int);
int geth() const;
int getm() const;
int gets() const;
void printtime() const;
private:
int h, m, s;
};
Начальные значения константному объекту присваивает конструктор. Если же данные-элементы объявлены как const, например,
const int h;
то используется инициализатор элементов, чтобы обеспечить конструктор объекта начальными значениями данных-элементов:
time::time(int hr, int mr, int sr)
:h(hr) //инициализатор элемента h
{ m=mr; s=sr; }
Перегрузка операций
С++ позволяет переопределить (перегрузить) действия большинства операций так, чтобы при использовании с объектами конкретного класса они выполняли заданные функции. Это дает возможность использовать при выполнении операций соответствующие типы данных точно так же, как стандартные. Обозначения собственных операций вводить нельзя; можно перегружать любые операции в С++, за исключением (помещены в круглые скобки):
(.), (->*), (.*), (?:), (::), (#), (##), (sizeof).
Перегрузка операций осуществляется с помощью функций специального вида (функций-операций)
тип operator операция(список параметров) {тело функции}
по правилам:
сохраняются количество аргументов, приоритеты и правила ассоциации, используемые в стандартных типах данных;
для стандартных типов переопределять операции нельзя;
функции-операции не могут иметь аргументов по умолчанию;
функции-операции наследуются (за исключением =);
функции-операции не могут определяться как static.
Функцию-операцию можно определить тремя способами: как функцию-элемент, как друга, как обычную функцию. В двух последних случаях функция должна принимать хотя бы один аргумент, имеющий тип класс, указателя или ссылки на класс. Но функция-операция, первый аргумент которой имеет тип – не данный класс (например, стандартный тип), не может определяться как функция-элемент класса.
Перегрузка унарных операций
а) Префиксный инкремент (декремент)
1) Функция-операция – как функция-элемент:
class time{
--------------------
time& operator++() {++h; return *this;}
--------------------
};
Каждый объект имеет указатель на себя this, определяемый автоматически при создании объекта. Указатель может использоваться только внутри функции-элемента класса. Указатель this – это указатель на текущий объект, т.е. на объект, вызвавший функцию.
2) Функция-операция – как дружественная функция:
class time{
friend time& operator++(time& t);
--------------------
};
Определение дружественной функции:
time& operator++(time& t) {++t.h; return t;}
3) Функция-операция – как просто функция. Она определена вне класса; и если объявлена – тоже вне класса.
time& operator++(time& t)
{ int k=t.geth();
k++;
t.seth(k);
return t;
}
//----------------------------------------------------------------------------------------------
Во всех трех случаях функция-операция используется одинаково:
void main(0
{ -------------
time t;
cout<<(++t).geth();
------------
}
//----------------------------------------------------------------------------------------------
б) Постфиксный инкремент (декремент)
Для отличия от функции-операции префиксного инкремента (декремента), функция-операция постфиксного инкремента (декремента) имеет параметр типа int:
class time {
----------------
time operator++(int) { h++; time t(*this); return t; }
--------------------------
};
Примечание. Локальный объект t создается как копия текущего объекта.
void main()
{ -----------
time t;
cout<<(t++).geth();
-------------
}
