Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП Лекции PDF / ООП 04 Лек Дружественные функции и классы.pdf
Скачиваний:
64
Добавлен:
15.02.2015
Размер:
306.49 Кб
Скачать

Лекция 4

Дружественные функции и классы

4

x = A.x + AB.GetX ( ) ;

y = A.y + AB.GetY ( ) ;

}

void Vec :: EndVec ( const Dot & A , Dot & B ) // описание функции-члена класса Vec

{

B.SetX ( A.GetX ( ) + x ) ;

B.SetY ( A.GetY ( ) + y ) ;

}

void EndVec ( const Dot & A , const Vec & AB , Dot & B ) // описание дружественной функции

{

B.x = A.x + AB.x ;

B.y = A.y + AB.y ;

}

#include "DotVec.h"

Файл Main.cpp

// подключение заголовочного файла DotVec

void main ( )

 

{

 

Dot A ('A', 3 , 4 ) , B ('B',-3 , 4 ) ; // вызов конструктора Dot ( char Name , double X , double Y )

Dot C ('C') , D ('D') ;

// вызов конструктора Dot ( char Name )

Vec AB ("AB", A , B ) ;

// вызов конструктора Vec ( char * pName , Dot A , Dot B )

Vec AC ("AC", 2 , 2 ) ;

// вызов конструктора Vec ( char * pName , double X , double Y )

C.EndVec ( A , AC ) ;

// вызов функции Dot :: EndVec ( const Dot & A , const Vec & AB )

AC.EndVec ( A , C ) ;

// вызов функции Vec :: EndVec ( const Dot & A , Dot & B )

EndVec ( A , AC , C ) ;

// вызов дружественной функции

}

// EndVec ( const Dot & A , const Vec & AB , Dot & B )

Эта программа демонстрирует важный случай применения неполного объявления класса: без применения этой конструкции в данном случае было бы невозможно объявить дружественную функцию для двух классов. Неполное объявление класса Vec дает возможность использовать его имя в объявлении дружественной функции еще до то определения. Необходимо отметить, что при неполном объявлении класса объявления классов должны находиться в одном заголовочном файле, в данном случае DotVec.h.

В приведенном примере объявлены классы точки Dot и вектора Vec и поставленная задача решена тремя различными способами.

Функция void Dot :: EndVec ( const Dot & A , const Vec & AB ) является членом класса Dot, получает константные ссылки на вектор и начало вектора и передаёт координаты конца вектора в текущую точку. Поскольку закрытые члены-данные класса Vec недоступны в классе Dot, то мы используем открытые функции-члены класса Vec GetY ( ) и GetX ( ). Функция-член класса вызывается оператором: C.EndVec ( A , AC ), где объект C является текущим, а объекты A и AC – параметрами.

Функция void Vec :: EndVec ( const Dot & A , Dot & B ) является членом класса Vec, получает константную ссылку на начало вектора и ссылку на конец вектора. При вычислениях используются значения проекций текущего вектора. Поскольку закрытые члены-данные класса Dot недоступны в классе Vec, то мы используем открытые функции-члены класса Dot GetX ( ), GetY ( ), SetX ( ), SetY ( ). Функция-член класса вызывается оператором: AC.EndVec ( A , C ), где объект AC является текущим, а объекты A и C – параметрами.

Функция friend void EndVec ( const Dot & A , const Vec & AB , Dot & B ) является дружественной классам Dot и Vec. Для этого она объявлена в обоих классах с ключевым словом friend. Функция получает константные ссылки на начало вектора и вектор, а также ссылку на конец вектора. Поскольку закрытые данные-члены обоих классов Dot и Vec доступны дружественной функции, то мы используем оператор “точка” для доступа к этим данным. Дружественная функция вызывается оператором

EndVec ( A , AC , C ).

Функции-члены, дружественные другому классу

Функция может быть членом одного класса и дружественной другому классу. Для демонстрации этого синтаксического приёма немного изменим предыдущий пример:

class Vec ;

Файл DotVec.h

// неполное объявление класса вектора

class Dot

// класс точки

{

 

• • •

 

Выжол Ю.А.

Объектно-ориентированное программирование