如果要访问类的私有成员变量,调用类的公有成员函数是唯一的办法,而类的私有成员函数则无法访问。
友元提供了另一访问类的私有成员的方案。友元有三种:
- 友元全局函数。
- 友元类。
- 友元成员函数。
1)友元全局函数
在友元全局函数中,可以访问另一个类的所有成员。
2)友元类
在友元类所有成员函数中,都可以访问另一个类的所有成员。
友元类的注意事项:
- 友元关系不能被继承。
- 友元关系是单向的,不具备交换性。
若类B是类A的友元,类A不一定是类B的友元。B是类A的友元,类C是B的友元,类C不一定是类A的友元,要看类中是否有相应的声明。
3)友元成员函数
在友元成员函数中,可以访问另一个类的所有成员。
如果要把男朋友类CBoy的某成员函数声明为超女类CGirl的友元,声明和定义的顺序如下:
class CGirl; // 前置声明。
class CBoy { ...... }; // CBoy的定义。
class CGirl { ...... }; // CGirl的定义。
// 友元成员函数的定义。
void CBoy::func(CGirl &g) { ...... }
#include <iostream>
#include <string>
using namespace std;
// 前置声明
class CGirl;
// 定义 CBoy 类
class CBoy {
public:
// 友元成员函数声明
void showGirlAge(CGirl& girl);
};
// 定义 CGirl 类
class CGirl {
private:
string name; // 私有成员
int age; // 私有成员
// 声明 CBoy 类的成员函数为友元
friend void CBoy::showGirlAge(CGirl& girl);
public:
CGirl(string n, int a) : name(n), age(a) {}
// 友元全局函数声明
friend void showGirlName(CGirl& girl);
// 友元类声明(示例中未具体实现另一个类)
// friend class CBoy;
};
// 定义友元全局函数
void showGirlName(CGirl& girl) {
cout << "Girl's Name: " << girl.name << endl;
}
// 实现友元成员函数
void CBoy::showGirlAge(CGirl& girl) {
cout << "Girl's Age: " << girl.age << endl;
}
int main() {
CGirl alice("Alice", 25);
CBoy bob;
// 使用友元全局函数访问私有成员
showGirlName(alice);
// 使用友元成员函数访问私有成员
bob.showGirlAge(alice);
return 0;
}
解释:
-
友元全局函数:
- 函数
showGirlName
被声明为CGirl
类的友元,因此它可以访问CGirl
的所有私有成员。
- 函数
-
友元类:
- 如果你想让整个
CBoy
类成为CGirl
类的友元,可以取消注释CGirl
中的friend class CBoy;
声明。这将允许CBoy
的所有成员函数访问CGirl
的私有和保护成员。
- 如果你想让整个
-
友元成员函数:
CBoy
类的成员函数showGirlAge
被声明为CGirl
的友元,允许它访问CGirl
的私有成员。
这个例子清楚地展示了如何使用友元来访问类的私有成员。友元功能在需要跨类共享数据但又不想公开这些数据的情况下非常有用。然而,使用友元时应当谨慎,因为它违背了封装的基本原则。