Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP.doc
Скачиваний:
7
Добавлен:
25.04.2019
Размер:
1.34 Mб
Скачать

3.2. Дружественные классы

Механизм дружественности в С++ допускает устанавливать отношение дружественности между классами. Под дружественным классом для некоторого класса C понимается класс, не входящий в число компонент класса C, но имеющий доступ ко всем его компонентам независимо от их уровня доступности. Все компонентные функции дружественного класса становятся также дружественными, хотя и не объявляются отдельно со спецификатором friend.

Чтобы сделать некоторый класс Y дружественным к классу X, нужно объявить его со спецификатором friend в теле класса X. В результате все компонентные функции класса Y получат доступ к закрытой и защищенной части класса X.

Ниже приведен фрагмент программы с использованием дружественного класса. В программе есть два класса. Первый (CPointN) представляет точку в N-мерном пространстве. Второй (CVectorN) моделирует вектор в N-мерном пространстве. Класс CVectorN для реализации интенсивно использует класс CPointN и поэтому объявляется к последнему дружественным. (Для упрощения в классы введены только некоторые из возможных компонентных функций.)

class CPointN { // точка

int __N; // мерность пространства

double * __Coords; // массив координат точки

friend class CVectorN; // объявление дружественного класса

public:

CPointN(int n, double d); // конструктор

~CPointN(); // деструктор

...

};

class CVectorN { // вектор

int __N; // мерность пространства

double * __Coords; // массив координат конца вектора

public:

CVectorN(const CPointN &, const CPointN &); // конструктор

~CVectorN(); // деструктор

double Norm() const; // норма вектора

...

};

// это пишем в файле реализации

// конструктор точки

CPointN::CPointN(int n, double d) {

__N = n; // определение мерности

// формирование массива координат

__Coords = new double[__N];

for(int i = 0; i < __N; i++) __Coords[i] = d;

}

// деструктор точки

CPointN::~CPointN() {

delete[] __Coords;

}

// конструктор вектора

CVectorN::CVectorN(const CPointN & s, const CPointN & d) {

__N = s.__N; // установка мерности вектора

__Coords = new double[__N]; // формирование массива координат

for(int i = 0; i < __N; i++)

__Coords[i] = d.__Coords[i] – s.__Coords[i];

}

// деструктор вектора

CVectorN::~CVectorN() {

delete[] __Coords;

}

double CVectorN::Norm() const {

double norm = 0.0;

for(int i = 0; i < __N; i++) norm += __Coords[i] * __Coords[i];

return norm;

}

...

За счет дружественности в конструкторе класса CVectorN происходит прямое обращение к компонентам точек.

Следует отметить, что дружественный класс не получает доступа к закрытым и защищенным компонентам вложенных классов для класса, дающего «дружбу». Отношение дружественности классов не является транзитивным, т.е. из того что X дружествен к Y, а Y дружествен к Z, не следует, что X будет дружественным к Z. Оно также не передается при наследовании, и чтобы сделать класс дружественным к иерархии классов, нужно объявить его таковым к каждому из них. Если класс объявляется дружественным к вложенному классу, то он также должен быть вложенным в ту же область действия имен, что и класс, предоставляющий «дружбу». Доступа к закрытым и защищенным компонентам объемлющего класса этот дружественный класс не имеет.

Рассматриваемый в следующей главе механизм вложения является еще одним способом определения отношений между классами и в сочетании с механизмом дружественности способен обеспечить весьма элегантные и эффективные решения.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]