1 友元
- 友元发生在函数和类之间或者类与类之间
- 友元不是类的一部分
- 友元不受类中访问级别的限制,可以直接访问具体类的所有成员
- 友元关系是单向的,不能传递
在类中用 friend 关键字对函数或类进行声明
1.1 函数友元
当一个函数声明为类的友元时,就可以访问类中的所有成员。
编程实验:函数是类的友元
// 18-1.cpp
#include<stdio.h>
#include<math.h>
class Point
{
public:
Point(int xx, int yy) : x(xx), y(yy){}
double getX() { return x; }
double getY() { return y; }
friend double func(Point& p1, Point& p2);
private:
double x, y;
};
double func(Point& p1, Point& p2)
{
double ret = pow(p1.x-p2.x, 2) + pow(p1.y - p2.y, 2);
ret = sqrt(ret);
return ret;
}
int main()
{
Point p1(1, 2);
Point p2(4, 6);
printf("p1(%f, %f)\n", p1.getX(), p1.getY());
printf("p2(%f, %f)\n", p2.getX(), p2.getY());
printf("%f\n", func(p1, p2));
return 0;
}
函数 func() 是类的友元,可以访问类中的所有成员,可以直接访问类中的私有成员。
$ g++ 18-1.cpp -o 18-1
$ ./18-1
p1(1.000000, 2.000000)
p2(4.000000, 6.000000)
5.000000
1.2 类友元
当一个类 A 声明为另一个类 B 的友元时,就可以访问类 B 中的成员。
// 18-2.cpp
#include<stdio.h>
class ClassC
{
public:
ClassC(const char* cc) : c(cc){}
friend class ClassB;
private:
const char* c;
};
class ClassB
{
public:
ClassB(const char* cc) : c(cc){}
friend class ClassA;
void getClassCName(ClassC& c)
{
printf("c.n = %s\n", c.c);
}
private:
const char* c;
};
class ClassA
{
public:
ClassA(const char* cc) : c(cc){}
void getClassBName(ClassB& b)
{
printf("b.n = %s\n", b.c);
}
private:
const char* c;
};
int main()
{
ClassA A("A");
ClassB B("B");
ClassC C("C");
A.getClassBName(B);
B.getClassCName(C);
return 0;
}
上面的代码中:
在类 B 中声明 friend class ClassA; 则 A 是 B 的友元;A可以访问 B 的成员。
在类 C 中声明 friend class ClassB;,则 B 是 C 的友元;B 可以访问 C 中的成员。
友元关系不具有传递行性,A 不是 C 的友元。
$ g++ 18-2.cpp -o 18-2
$ ./18-2
b.n = B
c.n = C
1.3 友元的缺点
友元直接破坏了面向对象的封装性,高效的同时得不偿失,已经逐渐被遗弃。
2 小结
1、类的友元可以是函数,也可以是类
2、友元不具备传递性
3、友元破坏了面向对象的封装性