- •Приложение г Лекция 1. Элементы Языка си Используемые символы
- •Константы
- •Идентификаторы
- •Ключевые слова
- •Использование комментариев в тексте программы
- •Лекция 2. Типы данных и их объявление
- •Категории типов данных
- •Целый тип данных
- •Данные вещественного типа
- •Указатели
- •Операции разадресации и адреса
- •Переменные перечислимого типа
- •Лекция 3. Выражения и присваивания Операнды и операции
- •Преобразования при вычислении выражений
- •Операции отрицания и дополнения
- •Операция sizeof
- •Мультипликативные операции
- •Аддитивные операции
- •Операции сдвига
- •Поразрядные операции
- •Логические операции
- •Операция последовательного вычисления
- •Условная (тернарная) операция
- •Операции увеличения и уменьшения
- •Простое присваивание
- •Составное присваивание
- •Приоритеты операций и порядок вычислений
- •Побочные эффекты
- •Преобразование типов
- •Лекция 3. Операторы
- •Оператор выражение
- •Пустой оператор
- •Составной оператор
- •Оператор if
- •Оператор switch
- •Оператор break
- •Оператор while
- •Оператор do while
- •Оператор for
- •Сумма чисел от 1 до 100
- •Микрожизнь
- •Оператор continue
- •Оператор return
- •Оператор goto
- •Лекция 4. Массивы
- •Поиск минимума, сортировка
- •Ввод-вывод, обнуление
- •Двумерный массив
- •Лекция 5. Структуры
- •Объединения (смеси)
- •Поля битов
- •Переменные с изменяемой структурой
- •Определение объектов и типов
- •Лекция 6. Инициализация данных
- •Определение и вызов функций
- •Ссылки как псевдонимы переменных
- •Ссылки в качестве параметров функции
- •Ссылка в качестве возвращаемого значения
- •Передача массивов
- •Прототип
- •Указатели на функцию
- •Рекурсия
- •Предварительная инициализация параметров функции
- •Функции с переменным числом параметров
- •Передача параметров функции main
- •Исходные файлы и объявление переменных
- •Объявления функций
- •Время жизни и область видимости программных объектов
- •Лекция 7. Инициализация глобальных и локальных переменных
- •Методы доступа к элементам массивов
- •Указатели на многомерные массивы
- •Операции с указателями
- •Массивы указателей
- •Лекция 8. Динамические объекты
- •1. Выделение памяти в соответствие с типом указателя
- •2. Выделение памяти под нетипизированный указатель
- •Лекция 9. Динамическое создание и уничтожение массивов
- •Директивы Препроцессора
- •Директива #include
- •Директива #define
- •Директива #undef
- •Лекция 10. Условные директивы препроцессора
- •Линейный односвязный список
- •Лекция 11. Объектно-ориентированный подход к программированию
- •Ссылки на Себя
- •Инициализация
- •Копирующий конструктор
- •Очистка
- •Законченный Класс
- •Доступ к членам
- •Статические Члены
- •Лекция 12. Наследование
- •Перегрузка Операций
- •Операции Преобразования
- •Стандартный ввод/вывод
- •Форматируемый вывод
- •Манипуляторы
- •Ввод-вывод двоичных данных
- •Ввод/вывод с диска
- •Ввод/вывод для типов данных, определенных пользователем
- •Шаблоны функций
- •Шаблоны классов
- •Лекция 14. Библиотека stl
- •Итераторы
- •Алгоритмы
- •Контейнеры
- •Функциональные объекты
- •Пример. Работа с контейнером vector
- •Пример 2. Алгоритмы и функциональные объекты
- •Лекция 15. Обработка исключительных ситуаций
- •Лекция 16. Rtti и приведение типов
- •Операция typeid
Шаблоны классов
Шаблон — это предписание для создания класса, в котором один или несколько типов либо значений параметризованы.
Предположим, что нам нужно определить класс, поддерживающий механизм очереди. Очередь – это структура данных для хранения коллекции объектов; они помещаются в конец очереди, а извлекаются из ее начала. Поведение очереди описывают аббревиатурой FIFO —«первым пришел, первым ушел».
Тогда объявление класса Queueбудет выглядеть примерно так:
class Queue {
public:
Queue();
~Queue();
Type& remove();
void add( const Type & );
bool is_empty();
bool is_full();
private:
// ...
};
Вопрос в том, какой тип использовать вместо Type? Предположим, что мы решили реализовать классQueue, заменивTypeнаint. ТогдаQueueможет управлять коллекциями объектов типаint. Если бы понадобилось поместить в очередь объект другого типа, то его пришлось бы преобразовать в типint, если же это невозможно, компилятор выдаст сообщение об ошибке.
Конечно, эту проблему можно решить, создав копию класса Queueдля работы с типомdouble, затем для работы с комплексными числами, затем со строками и т.д. А поскольку имена классов перегружать нельзя, каждой реализации придется дать уникальное имя:IntQueue,DoubleQueue,ComplexQueue,StringQueue. При необходимости работать с другим классом придется снова копировать, модифицировать и переименовывать.
Механизм шаблонов C++ позволяет автоматически генерировать такие типы. Шаблон класса можно использовать при создании Queueдля очереди объектов любого типа. Определение шаблона этого класса могло бы выглядеть следующим образом:
template <class Type>
class Queue {
public:
Queue();
~Queue();
Type& remove();
void add( const Type & );
bool is_empty();
bool is_full();
private:
// ...
};
Чтобы создать классы Queue, способные хранить целые числа, комплексные числа и строки, программисту достаточно написать:
Queue<int> qi;
Queue<complex> qc;
Queue<string> qs;
Пример: Реализация шаблона классаCStack— стек на основе динамического массива.
// Файл CStack.h
#ifndef _CStack_H
#define _CStack_H
#include <iostream.h>
#include <stdlib.h>
template <class Type>
class CStack {
private:
Type *data; //Массив для хранения стека
int top; //Индекс вершины стека
int size; //Макс. размер стека
public:
CStack(int); //Конструктор – передается максимальное количество элементов
~CStack() {free(data);}
void push(Type); //Добавление эл-та
int pop(Type &); //Выталкивание эл-та. Возвращает 0, если стек пуст
int isempty() {return !top;}
void print(); //Вывод содержимого стека
};
template <class Type>
CStack<Type>::CStack(int sz)
{
data=(Type*) calloc(sz, sizeof(Type));
top=0;
size=sz;
}
template <class Type>
void CStack<Type>::push(Type Item)
{
if (top==size)
{ //Если массив заполнен - расширить
size+=8;
data=(Type*)realloc(data, size*sizeof(Type));
}
data[top++]=Item;
}
template <class Type>
int CStack<Type>::pop(Type &Item)
{
if (!isempty())
{
Item=data[--top];
return 1;
}
else return 0;
}
template <class Type>
void CStack<Type>::print()
{
for (int i=top-1; i>=0; i--)
cout << data[i] << ' ' ;
cout << endl ;
}
#endif
//Тестирующая программа
#include <stdio.h>
#include <math.h>
#include "CStack.h"
int main(int argc, char* argv[])
{
printf("Int\n");
CStack <int> ti(2);
for (int i=0; i<4; i++)
ti.push(i);
ti.print();
int k;
for (int i=0; i<7; i++)
if (ti.pop(k)) printf("%d\n",k);
else printf("Empty\n");
printf("Double\n");
CStack <double> td(2);
for (int i=10; i<14; i++)
td.push(sqrt((double)i));
td.print();
double f;
for (int i=0; i<7; i++)
if (td.pop(f)) printf("%lf\n",f);
else printf("Empty\n");
getchar();
return 0;
}
Результаты работы программы:
Int
3 2 1 0
3
2
1
0
Empty
Empty
Empty
Double
3.60555 3.4641 3.31662 3.16228
3.605551
3.464102
3.316625
3.162278
Empty
Empty
Empty