C++语法之友元函数、友元类

本文首发于个人博客

友元

  • 友元包括友元函数和友元类
  • 如果将函数A(非成员函数)声明为类C的友元函数,那么函数A就能直接访问类C对象的所有成员
  • 如果将类A声明为类C的友元类,那么类A的所有成员函数都能直接访问类C对象的所有成员
  • 友元破坏了面向对象的封装性,但在某些频繁访问成员变量的地方可以提高性能

友元函数

如下代码:类Point。x和y坐标,成员变量是私有的,获取值通过get函数获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Point {
private:
int m_x;
int m_y;
public:
int getX() {
return m_x;

};
int getY() {
return m_y;

};
Point(int x, int y) :m_x(x), m_y(y) {}
void display() {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};

Point add(Point p1, Point p2) {
return Point(p1.getX() + p2.getX(), p1.getY() + p2.getY());
}

定义2个point,然后我们想把这两个point相加。就如下所示

1
2
3
4
5
6
7
8
9
int main(){
Point p1(10, 20);
Point p2(20, 30);

Point p3 = add(p1, p2);
p3.display();

return 0;
}
  • 能达到要求,但是问题是,调用add函数时候,每次获取x和y的值,都要通过getX()或者getY()来取值。因为m_x是私有成员,使用p1. m_x是会报错的。
  • 有什么办法能直接p1. m_x就可以访问么。同时m_x依然是私有成员

那就通过友元函数来实现

上的代码改成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class Point {
friend Point add(Point, Point);
private:
int m_x;
int m_y;
public:
int getX() {
return m_x;

};
int getY() {
return m_y;

};
Point(int x, int y) :m_x(x), m_y(y) {}
void display() {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};

Point add(Point p1, Point p2) {
return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}

也就是说把friend Point add(Point, Point)放在class Point中,这样说明这个函数是朋友了嘛,既然是朋友了,那可以直接访问私有成员变量。当然了其他函数想直接访问私有成员变量依然是不可以的。

友元类

既然和函数可以做朋友,那和类呢?答案是可以的。如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Point {
friend class Math;
private:
int m_x;
int m_y;
public:
int getX() {
return m_x;

};
int getY() {
return m_y;

};
Point(int x, int y) :m_x(x), m_y(y) {}
void display() {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};


class Math {
public:
Point add(Point p1, Point p2) {
return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}

void test() {
Point p1(10, 20);
p1.m_x = 10;
p1.m_x;
}
};

class Point 中声明了友元类friend class Math;那么在类Math中也是可以直接访问类Point中的私有成员变量。