Шаг 8 - Дружественные (friend) функции

Мы уже познакомились с основным правилом ООП - данные(внутренние переменные) объекта защищены от воздействий из вне и доступ к ним можно получить только с помощью методов(функций) объекта. Но бывают такие случаи, когда нам необходимо получить доступ к данным объекта не используя его интерфейс. Зачем это может понадобиться ? Как я уже как-то упоминал, при доступе к внутренним переменным объекта через его методы уменьшается эффективность работы за счет затрат на вызов метода. В большинстве случаев нам это не критично, но не всегда. В некоторых случаях это может играть существенную роль. Конечно, можно добавить новый метод к классу для получения прямого доступа к внутренним переменным. Однако, в большинстве случаев, интерфейс объекта (методы) спланирован для выполнения определенного круга операций, и наша функция может оказаться как бы ни к месту. А если хуже того, нам необходимо получить прямой доступ к внутренним данным двух разных объектов ? Возникает проблема. Именно для решения подобных задач и существует возможность описание функции, метода другого класса или даже класса как дружественного(friend).

Итак, как же работает этот механизм.

Для описания дружественной тому или иному классу функции(метода или класса) необходимо в описании этого класса объявить (описать) дружественную функцию с указанием ключевого слова friend. Если функция дружественна нескольким классам, то надо добавить это описание во все классы, к внутренним данным которых производим обращение. В большинстве языков ООП не имеет различия в какой раздел описания класса(publuc, protected или private) вставлено описание дружественной функции.

Но возникает такой вопрос: А как же наша хваленая защищенность данных, если можно получить доступ к данным напрямую ?

Но оказывается, что с точки зрения применимости механизма инкапсуляции, защищенность данных сохраняется, поскольку полностью исключается всякая возможность доступа к данным так, чтобы объект не был осведомлен об этом.

А теперь приведу несколько примеров использования дружественных функций(и не только) в языке С++.

//  Описание класса A
class A 
{
//...
void z();  // Описание функции  z  класса   A
}; 


// Описание класса B
class B 
{
//...
friend void A::z();  // Описание функции  z  класса  A  как дружественной 
// классу B, т.е. из функции  z  класса  A  можно
// получить доступ к внутренним переменным класса B
}; 

//  Описание класса  C
class C 
{
//...
friend class A;  // Описание класса  A  как дружественного классу  C,
 //  все функции класса  A  будут дружественны классу C и 
 //  из любой функции класса  A  можно получить доступ к 
 //  внутренним переменным класса  C
} 

Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Valeri Khromov - 5.02.2000