Вступление.

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

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

Для начала на этом простом примере познакомимся с синтаксисом:
class	banana{
int x,y;
public:
banana( void ){x=y=777;}
friend void f( banana );
};

void f(banana ob){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

Как видите, x и y – закрытые поля и ни одна функция не может до них добраться. Кроме f(banana ob). Заметьте, что f(banana ob) не является методом этого класса. Это видно из определения функции – нет указания пространства имен (banana::), хотя есть ещё один нюанс, скрытый от Ваших глаз. При вызове любого метода класса, в этот метод НЕЯВНО передается указатель *this, указывающий на объект, посредством которого был осуществлен вызов этого метода. Поэтому требуется передавать объект, с которым будет работать дружественная функция, как один из параметров.

Функция, может быть дружественной более чем одному классу:

class	banana;

class apple{
int a;
public:
void g( banana , apple );
};

class banana{
int x,y;
public:
banana( void ){x=y=777;}
friend void f( banana );
friend void g( banana , apple );
};

void f( banana ob ){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

void g(banana ob1 , apple ob2){
cout<<ob1.x<<endl;
cout<<ob1.y<<endl;
cout<<ob2.a<<endl;
}

Здесь вроде все очевидно. Кроме одной вещи – class banana. Такая конструкция называется предварительным объявлением. Оно нам потребовалось, потому что при всем желании мы не смогли бы организовать структуру программы таким образом, что бы классы banana и apple были определены до объявления функции g( banana ob1 , apple ob2 ).

Дружественные классы.

Дружественной к нашему классу, может быть функция другого класса:
class	banana;

class apple{
int a;
public:
void g( banana );
};

class banana{
int x,y;
public:
banana( void ){x=y=777;}
friend void f( banana );
friend void apple::g( banana );
};

void apple::g( banana ob ){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

void f( banana ob ){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

А может и целый класс:
class	banana;

class Foo{
public:
void f2( banana );
};

class banana{
int x,y;
public:
banana( void ){x=y=777;}
friend Foo;
};

void Foo::f2( banana ob ){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

Хоть я ещё и не рассказывал о наследовании, но всё-таки замечу, что дружественность не наследуется, например следующий код работать не будет:
class	banana;

class Foo{
public:
virtual void f2( banana );
};

class apple:public Foo{
int a;
public:
void f1( banana );
void f2( banana );
};

class banana{
int x,y;
public:
banana( void ){x=y=777;}
};

void apple::f1( banana ob ){
}

void apple::f2( banana ob ){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

void Foo::f2( banana ob ){
cout<<ob.x<<endl;
cout<<ob.y<<endl;
}

Вот вроде бы и все. Если возникнут проблемы, то способ связи прежний dodonov_a_a (___AT)inbox.ru.
Смежные вопросы:
Урок 1. Основы классов.
Урок 2. Конструкторы копий, оператор присваивания.
Урок 3. Перегрузка функций.
© 2004-2005 Savardge.ru
Hosted by uCoz