<<
>>

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

Как было отмечено ранее (раздел 3.1), механизм управления доступом позволяет выделить внутренние (private), защищенные (protected) и общедоступные (public) компоненты классов. Причем внутренние компоненты локализованы в классе и не доступны извне, а защищенные доступны только компонентным функциям класса и его наследникам.
Такое ограничение на доступ к внутренним и защищенным компонентам класса может оказаться неоправданно строгим. Оно может существенно сужать возможности наследования других классов от данного и сокращать количество вариантов его использования.

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

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

Функция не может стать другом класса «без его согласия». Для получения прав друга функция должна быть описана в теле класса со спецификатором friend. Именно при наличии такого описания класс предоставляет функции права доступа к защищенным и внутренним компонентам.

Пример 3.22. Внешняя дружественная функция.

#include ttinclude class FIXED {private: int a; public: FIXED(int v):a(v){} friend void show(FIXED);

};

void show(FIXED Par)

{cout«Par.a«endl; 11 функция имеет доступ к внутреннему полю а

Раг.а+=10;

cout«Par.a«endl; }

void main ()

{ clrscrQ;

FIXED аа(25);

coût « "результаты работы: ”«endl; show(aa); //выводит: 25 35

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

Пример 3.23. Дружественная функция - компонент другого класса.

#include

#include

class FLOAT; //объявление класса без его определения class FIXED {private: int a; public:

FIXED(int v):a(v){}

double Add(FLOAT);

void print (){cout «a« endl;}

};

class FLOAT {private: double b; public:

FLOAT(double val){b=val;} void printQ{cout «b « endl;}

friend double FIXED: :Add(FLOAT); /* компонентная функция класса FIXED объявляется дружественной классу FLOAT */

};

double FIXED::Add(FLOAT Par)

{return a+Par.b;} /* функция получает доступ к внутреннему полю

класса FLOAT */

void mainQ { clrscrO;

FIXED aa(25); FLOAT bb(45);

cout« "результаты работы: "«endl;

cout«aa.Add(bb)«endl; И выводит: 70

aa.print(); 11 выводит: 25

bb.printQ; 11 выводит: 45

getchQ;

}

Следует отметить некоторые особенности дружественных функций. Дружественная функция при вызове не получает указатель this. Объекты класса должны передаваться дружественной функции явно (через параметры).

Так как дружественная функция не является компонентом класса, на нее не распространяется действие спецификаторов доступа (public, protected, private). Место размещения прототипа дружественной функции внутри определения класса безразлично. Права доступа дружественной функции не изменяются и не зависят от спецификаторов доступа.

Использование механизма дружественных функций позволяет упростить интерфейс между классами. Например, дружественная функция может получить доступ к внутренним и защищенным компонентам сразу нескольких классов. Тогда из этих классов можно убрать компонентные функции, предназначенные только для обеспечения доступа к «скрытым» компонентам.

Поскольку ограничение доступа к дружественной функции не относится, работать она будет достаточно быстро, и написать ее не труднее, чем функцию доступа к обычной структуре C++.

Если необходимо, чтобы все функции некоторого класса имели доступ к внутренним полям другого класса, то весь класс может быть объявлен дружественным:

friend class .

Пример 3.24. Объявление дружественного класса.

^include

^include

class SHOW; II объявление класса без его определения class PAIR

{private: char *Head, *Tail; public:

PAIR(char *one,char *two):Head(one),Tail(two){} friend class SHOW; II объявление дружественного класса

};

class SHOW /*всем функциям класса SHOW доступны внутренние поля

класса PAIR*/

{private: PAIR Twins; public:

SHOW(char *one,char *two):Twins(one,two)Q void Head(){cout «Twins.PAIR::Head « endl;} void TailQ{cout «Twins.PAIR::Tail« endl;}

};

void mainQ { clrscrO;

SHOW aa("HELLO", "FRIEND");

coût « "результаты работы: "«endl; aa.Head(); И выводит: HELLO аа. Tail(); И выводит: FRIEND getchQ;}

<< | >>
Источник: Г.С.Иванова, Т.Н.Ничушкина, Е.К.Пугачев. Объектно- ориентированное программирование. 2001

Еще по теме Дружественные функции и классы:

  1. Относитесь к сомнению, как к дружественному напоминанию
  2. 6. Воспитывая доброго и дружественного человека, вы воспитываете хорошего семьянина
  3. Функции журналистики. Понятие функцию Многообразие социальных и информационных потребностей общества – объективная основа функций журналистики.
  4. “Не язык — функция поэта, а поэт — функция языка”
  5. Школьный класс
  6. Одиночки в классе
  7. ПЕРВЫЙ КЛАСС
  8. ПЯТЫЙ КЛАСС
  9. 6.3. Женщина высшего класса
  10. 5. Критическая теория и рабочий класс.