Читайте также: |
|
Выше мы уже говорили о том, что существует три уровня внутренней “защиты” для различных членов класса: public, protected и private. В случаях, когда члены класса объявлены в секциях private и protected, нет возможности напрямую обратиться к ним извне класса, в котором они объявлены. Тем не менее, это правило может быть нарушено использованием в классе ключевого слова friend так, что мы можем позволить, например, некоторым внешним функциям иметь доступ к закрытым и защищенным членам класса. В частности, иногда желательно иметь непосредственный доступ извне к скрытым полям класса для того, чтобы расширить интерфейс класса. Для этого служат дружественные функции.
Класс, как и функция, также может быть объявлен “другом” другого класса. Функции-члены дружественного класса могут иметь доступ ко всем закрытым членам основного класса. Отношение “дружбы” не является ни коммутативным, ни транзитивным.
Пример 10-3.1
class Circle; // опережающее объявление
class Point
{
float x;
float y;
public:
Point (): x(0), y(0) { } // конструктор
Point (float a, float b): x(a), y(b) { } // другой конструктор
friend Circle; // дружественный класс
friend const Point middle(const Point & u, const Point & v); // дружественная функция
};
const Point middle(const Point & u, const Point & v)
{
return Point((u.x + v.x) / 2, (u.y + v.y) / 2);
// прямой доступ к полям x и y
}
class Circle
{
Point center;
float radius;
public:
Circle(): radius(0) {center.x = 0; center.y = 0;}
// прямой доступ к x и y
Circle& move(float a, float b)
{
center.x += a;
center.y += b;
return *this;
}
// прямой доступ к x и y
};
Дружественные функции нужно применять при явной необходимости, поскольку они нарушают принцип инкапсуляции и, таким образом, затрудняют отладку и модификацию программы. Но в практике бывают ситуации, когда некоторый класс является функционально перегруженным и его наращивание затруднительно. Тогда дальнейшую обработку данных класса выносят во внешние дружественные функции.
Ниже перечислены правила описания и особенности дружественных функций.
Одна функция может быть дружественной сразу нескольким классами.
Еще один пример:
// friend class#include <iostream.h> class CSquare; class CRectangle { int width, height; public: int area (void) {return (width * height);} void convert (CSquare a);};
class CSquare { private: int side; public: void set_side (int a) {side=a;} friend class CRectangle;};void CRectangle::convert (CSquare a) { width = a.side; height = a.side;}
int main () { CSquare sqr; CRectangle rect; sqr.set_side(4); rect.convert(sqr); cout << rect.area(); return 0;}
В этом примере мы объявили CRectangle “другом” класса CSquare, так что CRectangle имеет доступ к закрытым членам CSquare.
Дата добавления: 2015-11-16; просмотров: 58 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Прямая инициализация полей в классе не допускается. | | | Указатели на поля класса |