
- •В.В. Чуркин технологии программирования
- •Содержание
- •Введение
- •Указатели. Операции над указателями Операции адресации и разыменования.
- •Арифметические операции.
- •Присваивание указателей.
- •Смещение и индексирование указателей.
- •Функции
- •Объявление функции (прототип)
- •Параметры функции
- •Встроенные функции
- •Функции с параметрами со значениями по умолчанию
- •Параметры функции main()
- •Рекурсивные функции
- •Перегрузка функций
- •Шаблоны функций
- •Указатели на функции
- •Объявление и инициализация массива указателей на функции:
- •Указатель на функцию как возвращаемое функцией значение
- •Выделение и освобождение динамической памяти
- •Символьные и строковые данные Символьные константы
- •Строковые константы (строки)
- •Символьные переменные
- •Строки – переменные
- •Специальные функции ввода-вывода строк
- •Стандартная библиотека функций языка с
- •Файлы Потоковый ввод-вывод в языке с Функции верхнего уровня файлового ввода-вывода
- •Открытие и закрытие потока
- •Текстовый режим
- •Бинарный режим
- •Закрытие файла
- •Функции в языке c для работы с файлами
- •Двоичный (бинарный) режим обмена с файлами
- •Строковый обмен с файлами
- •Форматный обмен с файлами
- •Позиционирование в потоке
- •Ввод-вывод нижнего уровня
- •Открытие / закрытие файла
- •Чтение и запись данных
- •Произвольный доступ к файлу
- •Позиционирование файлов
- •Сортировки числовых массивов Принцип наименьших привилегий
- •Обменная сортировка (SwapSort)
- •Сортировка выбором (SelectSort)
- •Пузырьковая сортировка (BubbleSort)
- •Сортировка вставками (InsertSort)
- •Быстрая сортировка (QuickSort)
- •Поиск в числовых массивах
- •Структуры
- •Форматы определения структурных типов
- •Форматы определения объектов структурных типов
- •Операции над объектами структурного типа
- •Доступ к элементам объектов структурного типа
- •Структуры, массивы и указатели
- •Объединения (смеси)
- •Оператор switch (переключатель)
- •Динамические структуры данных
- •Реализация стека с помощью массива
- •Очередь
- •Очередь приоритетов
- •Реализация очереди с помощью массива
- •Линейные списки
- •Функции для работы с двунаправленным линейным списком
- •Реализация списка с помощью массивов
- •Поиск хэшированием
- •Бинарные деревья
- •Бинарное упорядоченное дерево (дерево поиска)
- •Идеально сбалансированное дерево
- •Операции с бинарным упорядоченным деревом
- •Удаление узла из дерева
- •Обход (просмотр) дерева
- •Реализация дерева с помощью массивов
- •Вывод динамических структур в файл и чтение их из файла
- •Сбалансированные (avl) деревья
- •Алгоритм avl-вставки.
- •Повороты
- •Классы и объектно-ориентированное программирование
- •Объявление класса
- •Определение класса (реализация класса)
- •Использование класса (драйвер класса)
- •Доступ к элементам класса
- •Отделение интерфейса от реализации
- •Обслуживающие функции-утилиты
- •Конструкторы
- •Windows-программы в Builder
- •Структура головного файла проекта
- •Структура заголовочного файла модуля формы (“Unit1.H”)
- •Структура файла реализации модуля формы (“Unit1.Cpp”)
- •Области видимости (или области действия) переменных в блоках. Время жизни переменных
- •Доступ к свойствам и функциям-элементам (методам) объектов, переменным и функциям в приложении, содержащем одну форму
- •Константные объекты и константные функции-элементы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Перегрузка операции индексирования []
- •Композиция классов
- •Дружественные функции класса
- •Дружественный класс
- •Использование указателя this
- •Статические элементы класса
- •Шаблон класса для статически и динамически создаваемых объектов
- •Конструктор 1
- •Деструктор
- •Вызовы конструкторов и деструкторов
- •Перегруженная операция присваивания
- •Конструктор 2 (конструктор копирования, конструктор копии)
- •Наследование. Иерархия классов.
- •Ключи доступа
- •Пример простого наследования (точка, круг)
- •Правила наследования функций-элементов. Вызовы конструкторов и деструкторов в иерархии
- •Виртуальные функции и полиморфизм
- •Правила определения и наследования виртуальных функций
- •Позднее (динамическое) связывание
- •Полиморфизм. Абстрактные и конкретные классы
- •Учебная литература (основная)
- •Учебная литература (для углубленного изучения)
- •Учебно-методические издания
Композиция классов
Суть композиции классов состоит в том, что объекты одних классов используются как элементы других классов.
Пример: служащий с датами рождения и приёма на работу.
//------------------------------------------------------------------------------
class date{
public:
date(int=1, int=1, int=1980); //конструктор с умолчанием
void print() const;
private:
int m, d, y;
};
//-------------------------------------------------------------------------------
class employee {
public:
employee (char*, char*, int, int, int, int, int, int);
void print() const;
private:
date bdat; // дата рождения
date hdat; // дата приема на работу
};
//---------------------------------------------------------------------------------
employee:: employee(char* f, char* l, int bm, int bd, int by,
int hm, int hd, int hy)
:bdat(bm, bd, by), hdat(hm, hd, hy)
{------------}
//----------------------------------------------------------------------------------
void main()
{ employee e(“Петров”,”Иван”, 7, 24, 1979, 6, 11, 2000);
----------------------------------------
}
//---------------------------------------------------------------------------------
Программа создает объект e класса employee, задает начальные значения данным-элементам. Конструктор employee принимает 8 аргументов. Инициализаторы элементов (отделены через ‘:’) указывают, что аргументы employee передаются конструкторам объектов-элементов.
Если инициализаторы элементов не заданы, будет автоматически вызван конструктор (с умолчанием) объекта-элемента. Затем значения, установленные конструктором с умолчанием, могут быть изменены с помощью функций записи “set”. Если же в этом случае не предусмотрен конструктор с умолчанием, то появится ошибка – объект-элемент не будет инициализирован.
Дружественные функции класса
Определяются вне области действия этого класса, но имеют право доступа к закрытым private и защищенным protected элементам данного класса.
//-------------------------------------------------------------------
#include <iostream.h>
class count {
friend void setx(count&, int); // объявление дружественной функции
public:
count() {x=0;} //конструктор
void print() const { cout<<x<<endl; }
private:
int x;
};
//Определение дружественной функции
void setx(count& c, int v)
{ c.x=v; } //доступ к x – через ссылку c
//--------------------------------------------------------
void main()
{ count ob;
ob.print(); //0
setx(ob, 10);
ob.print(); //10
}
//----------------------------------------------------------------------
Дружественный класс
class BinSTree; //предварительное объявление класса
class TreeNode {
friend class BinSTree;
----------------------
-------------------
};
Дружественный класс BinSTree имеет доступ через свои функции-элементы к функциям-элементам класса TreeNode.
Использование указателя this
Каждый объект сопровождается указателем на самого себя. this – это неявный аргумент во всех ссылках на элементы внутри этого объекта. this можно использовать явно, например, для определения собственного адреса объекта.
1) Указатель this неявно используется в функциях-элементах класса для ссылки как на данные-элементы, так и на функции-элементы объекта. Если функция-элемент – неконстантная, то this – это константный указатель на неконстантный объект, а если функция-элемент – константная, то this – константный указатель на константный объект. this используется только внутри функций-элементов класса. Каждая функция-элемент имеет доступ к указателю this на объект, для которого эта функция вызвана.
Пример неявного и явного использования this для ссылки на элементы объекта.
//-----------------------------------------------------------------
#include <iostream.h>
class test {
public:
test(int=0);
void print() const;
private:
int x;
};
//-------------------------------------------
test::test(int a) { x=a; }
//---------------------------------------------
void test::print() const
{ cout<<x<<endl //неявное
<<this->x<<endl //явное
<<(*this).x<<endl; //явное
}
//--------------------------------------------
void main()
{ test a(12);
a.print(); //12
//12
//12
}
//--------------------------------------------------------------------------
2) Сцепленные вызовы функций-элементов
//---------------------------------------------------
#include <iostream.h>
class time {
public:
time(int=0, int=0, int=0);
time& seth(int); //установка часа
time& setm(int); //установка минут
time& sets(int); //установка секунд
-----------------------
private:
int h, m, s;
};
//----------------------------------------------------
time& time::seth(int hs)
{ h=(hs>=0&&hs<24)?hs:0;
return *this;
}
//-----------------------------------------------------
void main()
{time t;
t.seth(10).setm(15).sets(20); //выполнение слева-направо
t.printtime(); //10:15:20
}
//------------------------------------------------------
Каждая из функций-элементов - seth(), setm(), sets() – возвращает *this с типом возврата time&, что дает возможность сцепленных вызовов функций-элементов класса time. Операция (.) имеет ассоциативность слева-направо, так что сначала выполняется t.seth(10), а затем возвращает ссылку на объект t как значение вызова этой функции.