- •Базовое ядро языка Элементы программы.
- •Комментарии
- •Инструкция – выражение
- •Инструкция
- •Определение функции
- •Заголовок функции
- •Прототипы функций
- •Аргументы по умолчанию.
- •Перегрузка функций
- •Встраиваемые функции
- •Стек до блока Вошли в блок Вышли из блока
- •Индексирование
- •Int a [100]; одномерный массив
- •Int b [3][5]; двухмерный массив
- •Int c [7][9][2]; трехмерный массив
- •Передача массивов функциям
- •Объявления ссылок и вызовов по ссылке
- •Функции-члены класса
- •Доступ: закрытый и открытый
- •Область видимости класса
- •Оператор разрешения области видимости ::
- •Вложенные классы
- •Статические члены данных
- •Указатель this
- •Функции-члены типа static и const.
- •Изменчивость (mutable)
- •Создание и уничтожение объектов
- •Классы с конструкторами
- •Конструкторы как преобразования
- •Создание динамического стека
- •Классы с деструкторами
- •Пример: динамически размещаемые строки
- •Ad hoc полиморфизм
- •Алгоритм выбора перегруженной функции
- •Перегрузка операторов
- •Перегрузка бинарных операторов
- •Перегрузка операторов присваивания и индексирования
- •Перегруженные операторы ввода-вывода « и »
- •Перегрузка оператора ( ) для индексирования
- •Операторы указателей
- •Указатель на член класса
- •Перегрузка new и delete
- •Наследование.
- •Методология объективно-ориентированного проектирования
- •Виртуальные функции
- •Абстрактные базовые классы
Пример: динамически размещаемые строки
Языку C++ недостает собственного строкового типа. Стандартная библиотека предоставляет шаблонный строковый класс — тип, который используется все чаще и чаще. Старое строковое представление выглядело как указатель на char. В этом представлении конец строки обозначался нулевым символом ' \0 '.
В этом разделе мы разработаем полезныи строковый АТД, в котором длина объявлена как private.
Реализация будет использовать строковые функции из библиотеки string.h для оперирования вышеупомянутым представлением строк с помощью указателей.
………Этот тип позволяет объявлять строки my_string, присваивать с помощью копирования одну my_string другой, печатать строки и объединять две строки типа my_string. Скрытое представление является указателем на char и содержит переменную len, в которой хранится текущая длина строки типа my_string.
Следующая программа тестирует класс my_string, выполняя конкатенацию нескольких строк типа my_string.
Пример: односвязный список
Разработаем тип данных для односвязного списка. Он является прототипом для многих динамических АТД, которые называются ссылающимися на себя структурами (self-referential structure). Такие типы данных содержат члены-указатели, которые ссылаются на объекты своего собственного типа. Они служат основой для многих полезных контейнерных классов.
Операции над списком
1. prepend: добавляет в голову списка 2. first: возвращает указатель на первый элемент 3. print: печатает содержимое списка 4. del: удаляет первый элемент
5. release: уничтожает список
Связующий член next указывает на следующий slistelem в списке. Переменная data в этом примере является простой переменной, но она может быть заменена на сложный тип, способный хранить целую порцию информации. Конструктор инициализует голову списка slist (указатель h ) значением 0, которое называется постоянной нулевого указателя (null pointer constant) и может быть присвоено указателю любого типа. В связных списках она обычно обозначает пустой список или значение «конец списка». Функция-член prepend () строит структуру списка:
void slist::prepend(char с)
{
slistelem* temp = new slistelem; //создание элемента
assert(temp != 0);
temp -> next = h; //связь с slist
temp -> data = c;
h = temp; //изменение головы списка
}
Новый элемент списка размещается в свободной памяти, а его член данных инициализуется единственным аргументом с. Его связующий член next устанавливается на прежнюю голову списка. Затем голова (указатель h) изменяется так, чтобы указывать на только что созданный элемент как на новый первый элемент списка.
Строки, использующие семантику ссылок
В следующем примере мы создадим класс my_string, имеющий ссылочную семантику копирования. Этот класс использует поверхностное копирование, поскольку копирование заменено присваиванием указателей. Показанная техника обычна для агрегатов данных подобного типа. Будем использовать класс str_obj для создания значений фактических объектов. Тип str_obj является необходимой деталью реализации my_string. Данная деталь не может быть помещена непосредственно в my_string без разрушения отношения (возможно, многие-к-одному) между объектами типа my_string и ссылочными значениями типа str_obj. Значения my_string содержатся в str_obj, который является дополнительным классом только лишь для использования классом my_string. Открыто используемый класс my_string управляет экземплярами str_obj, и иногда называется управляющим классом (handler class).
//Строки my_string с подсчетом ссылок
#include <string.h> #include <iostream.h> #include <assert.h>
class str_obj {
public: int len, ref_cnt; char* s;
str_obj() : len(0), ref_cnt(l)
{ s = new char[l]; assert(s != 0); s[0] = 0; }
str_obj(const char* p) : ref_cnt(l)
{ len = strlen(p); s = new char[len + 1] ;
assert(s != 0); strcpy(s, p); }
~str_obj() { delete []s; } };
Класс str_obj объявляет объекты, которые используются my_string. Обратите внимание, что класс str_obj применяется в основном для создания и уничтожения объектов, использующих свободную память. При создании str_obj переменная ref_cnt инициализуется единицей.
…….. Каждый| раз, когда счетчик ссылок объекта уменьшается, он проверяется на предмет удаления.
Преимущество перед обычным копированием очевидно. Очень большие агрегаты копируются по ссылке с помощью всего нескольких операций.
Для хранения счетчика ссылок требуется небольшое количество дополнительной памяти. Кроме того, каждое возможное изменение указателя влечет операцию со счетчиком ссылок. Деструктор также должен проверять счетчик ссылок перед фактическим удалением. my_string:: ~ my_string ()
{ if (--st -> ref_cnt = =0) delete st; }