Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вторая часть лекции.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
592.9 Кб
Скачать

Void ff(cl1 cl,cl2 c2) { тело_функции }

Кроме того, класс может быть дружественным другому классу. Это означает, что все компонентные функции класса являются дружественными для другого класса. Дружественный класс должен быть определен вне тела класса, "предоставляющего дружбу". Например, так:

class X2 {

friend class X1;

};

class X1 { ... // Определение дружественного класса

Void f1(...);

Void f2(...);

};

В данном примере функции f1 и f2 из класса X1 являются друзьями класса Х2, хотя они описываются без спецификатора friend.

Все компоненты класса X2 доступны в дружественном классе X1. Дружественный класс может быть определен позже (ниже), нежели описан как дружественный.

Классы и шаблоны

Шаблоны, которые иногда называют родовыми или параметризованными типами, позволяют создавать (конструировать) семейства родственных функций и классов [2], [9].

Как уже говорилось в главе 6, шаблон семейства функций {function template) определяет потенциально неограниченное множество родственных функций. Он имеет следующий вид:

template <список_параметров_шаблона> определекие_функции

Здесь угловые скобки являются неотъемлемым элементом опреде­ления. Список параметров шаблона должен быть заключен именно в угловые скобки.

Аналогично определяется шаблон семейства классов:

template <список_параметров_шаблона> определение класса

Шаблон семейства классов определяет способ построения отдельных классов подобно тому, как класс определяет правила построения и формат отдельных объектов. В определении класса, входящего в шаблон, особую роль играет имя класса. Оно является не именем от­дельного класса, а параметризованным именем семейства классов.

Как уже отмечалось в связи с шаблонами функций, определение шаблона может быть только глобальным.

Следуя авторам языка и компилятора Си++ [2, 9], рассмотрим векторный класс (в число данных входит одномерный массив). Какой бы тип ни имели элементы массива (целый, вещественный, с двойной точностью и т.д.), в этом классе должны быть определены одни и те же базовые операции, например доступ к элементу по индексу и т.д. Если тип элементов вектора задавать как параметр шаблона класса, то система будет формировать вектор нужного типа (и соответствующий класс) при каждом определении конкретного объекта.

Следующий шаблон позволяет автоматически формировать классы векторов с указанными свойствами:

template <class T> // Т - параметр шаблона

class Vector {

Т *data; // Начало одномерного массива

Int size; // Количество элементов в массиве

public:

Vector(int); // Конструктор класса vector

~Vector() { delete[] data; } // Деструктор

// Расширение действия (перегрузка) операции "[]":

Т& operator[] (int i) { return data[i]; }

};

// Внешнее определение конструктора класса:

template <class T>

Vector <T>::Vector(int n) { data = new T[n]; size = n; };

Когда шаблон введен, у программиста появляется возможность определять конкретные объекты конкретных классов, каждый из которых параметрически порожден из шаблона. Формат определения объекта одного из классов, порождаемых шаблоном классов: