Дружественная функция класса А - это функция, не являющаяся членом класса А, но имеющая право доступа к его private и protected элементам. Во всех прочих отношениях это обычная функция. Такие функции используются при перегрузке операций и в тех случаях, когда требуется совместная обработка объектов разных классов. Следует отметить, что введение в C++ дружественных функций в некоторой степени противоречит принципу инкапсуля¬ции. Одна и та же функция может использоваться для доступа к за¬крытым элементам разных классов, что снижает степень защиты данных. Поэтому использование дружественных функций следует ограничить.
Для того чтобы сделать функцию дружественной, следует в пределах класса объявить эту функцию с ключевым словом friend, например
class Aclass
{
int n;
friend int next(Aclass x);
public:
Aclass (int c=0)
{
n = c;
}
};
int next(Aclass x)
{
return x.n=x.n+1;
}
void main()
{
Aclass a(10);
cout<< next(a)<<endl;
Aclass b;
cout<< next(b)<<endl;
}
При обращении к элементам класса дружественные функции должны явно ссылаться на объект, так как указатель this им не пе¬редается. Это могут быть объекты, созданные внутри дружественной функции, или объекты, переданные ей в качестве параметра.
Функция может быть дружественной двум и более классам од¬новременно. В каждом классе она должна быть объявлена как friend. Обычно при этом ей передаются в качестве параметров объекты двух (и более) классов. По правилам C++ эти классы должны быть уже известны до того, как их используют в качестве параметров. Однако описать оба класса перед включением в них дружественной функции логически невозможно. Для преодоления этого противоречия используется так называемая ссылка вперед - объявление класса без его фактического описания.
Пример:
class Bclass; //ссылка-вперед
class Aclass
{
int n;
public:
Aclass (int c=1)
{
n = c;
}
friend int xt(Aclass x, Bclass y);
};
class Bclass
{
int i;
public:
Bclass (int c=1)
{
i = c;
}
friend int xt(Aclass x, Bclass y);
};
int xt(Aclass x,Bclass y)
{
return x.n+y.i;
}
void main()
{
Bclass b;
Aclass a;
cout<< xt(a,b);
}
Здесь в функции xt() складываются защищенные данные двух классов. Это i для класса Bclass и n для класса Aclass.
Дружественность классов нетранзитивна, т.е. из А (friend),B (friend) С не следует, что A (friend) С.
Обратите внимание на то, что в обоих случаях, в функцию передается объект, или объекты классов. При вызове функции, происходит неявное создание нового объекта-копии переданного объекта. При возврате из функции, этот объект уничтожается, путем неявного вызова деструктора, дабы освободить выделенную для него память.
Статические и нестатические члены кл