-
友元利弊:
友元不是类的成员但能访问类中的私有成员。友元的作用在于提高程序的运行效率,但也破坏了类的封装。 -
注意事项:
(1)友元关系不能被继承;
(2)友元关系是单向的,不具有交换性;
(3)友元关系不具有传递性;
一、友元函数
- 类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员
- 尽管友元函数的原型有在类的定义中出现过,但是 友元函数并不是成员函数
- this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象
- 友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针
1. 友元函数是全局函数
class A
{
friend void printA(const A &a);
public:
void printA();
private:
string name {"C++"};
int id {1024};
};
void A::printA(){
cout << "name = " << this->name << "\t id = " << this->id << endl;
}
// 请注意:printA() 不是任何类的成员函数
void printA(const A &a){
cout << "name = " << a.name << "\t id = " << a.id << endl;
}
int main()
{
A a;
printA(a);
a.printA();
return 0;
}
输出:
Start
name = C++ id = 1024
name = C++ id = 1024
0
Finish
2. 友元函数是类的成员方法
小技巧:为了防止相互嵌套,可以将其中一个类的声明和实现拆开
class Point;
class PointManager{
public:
double getDistance(Point &p1, Point &p2);
private:
};
class Point{
friend double PointManager::getDistance(Point &p1, Point &p2);
public:
Point(int x, int y){
this->x = x;
this->y = y;
}
private:
int x;
int y;
};
double PointManager::getDistance(Point &p1, Point &p2){
int dx = p1.x - p2.x;
int dy = p1.y - p2.y;
return sqrt(dx * dx + dy * dy);
}
int main( )
{
Point p1(1, 1), p2(3, 1);
PointManager pm;
cout << pm.getDistance(p1, p2) << endl;
return 0;
}
输出:
Start
2
0
Finish
二、友元类
class A{
friend class B; // 将 B 声明为友元类后,在 B 中 A 就是透明的
public:
A(int a){
this->a = a;
}
void printA(){
cout << "a = " << this->a << endl;
}
private:
int a;
};
class B{
public:
B(int b){
this->b = b;
}
void printB(){
A a(10);
cout << "print a in b: " << a.a << endl;
cout << "b = " << this->b << endl;
}
private:
int b;
};
int main( )
{
B b(-10);
b.printB();
return 0;
}
Start
print a in b: 10
b = -10
0
Finish