一、 友元
对于类中的私有部分访问,公有方法是唯一途径,因此,需要友元类来提供访问权限
友元有三种:
1. 友元函数
2. 友元类
3. 友元成员函数
二、创建友元函数
创建友元函数步骤:将其原型放到类声明中 原型前加上关键字friend
特征: 虽然是在类声明的,但是它不是成员函数,不能使用成员运算符. 来调用
虽然它不是成员函数,但是访问权限和成员函数相同
三、示例
友元类需要在函数定义最前边加上friend关键字
我们定义一个游戏类,假设我们声明了一个成员函数,并且重载运算符
//头文件.h
class Game {
int level;//定义第几关
double score;//定义得分
public:
Game(const int s, const double& a); //定义构造函数
Game(); //定义默认构造函数
void set(double a); //设置现在的得分
void show() const; //打印出得分
Game operator*(const double& num); //游戏中得分翻倍
friend Game operator*(double, Game&); //定义友元类,左边参数是double类型,右边是Game类型,可以直接访问这个对象的私有变量
friend ostream& operator<<(ostream& os, Game& game);
};
可在另一个文件里对友元函数进行实现,此时不需要加 :: 作用域运算符,并且可以直接访问类中的私有成员
//文件1.cpp
Game operator*(double x, Game& a) {
a.score = a.score * x; //这里a*x是因为,a是类对象,
//a*x实际上调用了成员函数重载的*,a.operator*(double)这个函数,然后a.operator*(double)这个函数返回的是Game类,所以用a本身来接受
return a ;
}
四 常见的友元:重载<<运算符
在上边的示例中,假设有一个Game对象pvz ,为了显示Game的所有值,之前使用的show()方法,但是如果可以下边这样操作
cout<<pvz; //将Game 对象pvz打印出来,但是一般的情况下,cout是不能打印的
此时我们需要重载运算符 <<
如果我们使用成员函数重载<<运算符,那么在调用的时候只能pvz<<cout;因为顺序必须是Game类.方法,所以我们不妨使用友元函数如下
friend void operator<<(ostream& os, Game& a);
void operator<<(ostream& a, Game& game) {
cout << "现在是第" << game.level << "关" << endl; //打印关卡
cout << "您当前得分是:" << game.score << endl; //打印当前得分
}