
Лекция 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 |
// класс точки |
{ |
|
• • • |
|
Выжол Ю.А. |
Объектно-ориентированное программирование |