友元的概念:
遵循一定规则而使对象以外的软件系统能够不经过消息方式而直接访对象内封装的数据成员的技术方法便是友元。
友元是面向对象系统与过程系统衔接纽带。
友元有:友元函数,友元成员,友元类
友元可以放在类的公有,私有,保护部分。
友元函数
1.友元函数可访问类的私有和保护成员,但不是类的成员函数
2.友元函数不能用const修饰
3.友元函数可以在类定义的任何地方声明,不受类访问限定符限制
4.一个函数可以是多个类的友元函数
在类的定义中用friend声明了一个外部函数或其他类的成员函数(public和private均可)后,这个外部函数称为类的友元函数。
由干友元函数不是类的成员,所以没有this指针,访问该类的对象的成员时,必须使用对象名,而不能直接使用类的成员名。
虽然友元函数是在类中说明的,但其名字的作用域在类外,作用域的开始点在说明点、结束点和类名相同。因此,友元说明可以代替该函数的函数说明。
#include <bits/stdc++.h>
using namespace std;
class Point {
private:
int x, y;
friend float dis(Point &p1, Point &p2);
//可以是public,也可是private
public:
Point(int i, int j) { //构造函数,带缺省参数值
x = i;
y = j;
}
void disp() {
cout << "(" << x << "," << y << ")";
}
};
float dis(Point &p1, Point &p2) { //友元函数的实现
//友元函数中可访问类的private成员
float d = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
return d;
}
int main() {
Point p1(1, 2), p2(4, 5); //声明两个Point类的对象p1和p2
p1.disp(); //显示点p1的信息
cout << "与";
p2.disp(); //显示点p2的信息
cout << "距离=" << dis(p1, p2) << endl; //利用友元函数计算两点举例
return 0;
}
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。
友元关系不能传递->如果B是A的友元,C是B的友元,则不能说明C时A的友元。
class Date; // 前置声明
class Time
{
friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
员变量
public:
Time(int hour, int minute, int second):_hour(hour) , _minute(minute) , _second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month) , _day(day)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
// 直接访问时间类私有的成员变量
_t._hour = hour;
_t._minute = minute;
_t.second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
#include <iostream>
using namespace std;
class Box
{
double width;
public:
friend void printWidth(Box box);
friend class BigBox;
void setWidth(double wid);
};
class BigBox
{
public :
void Print(int width, Box &box)
{
// BigBox是Box的友元类,它可以直接访问Box类的任何成员
box.setWidth(width);
cout << "Width of box : " << box.width << endl;
}
};
// 成员函数定义
void Box::setWidth(double wid)
{
width = wid;
}
// 请注意:printWidth() 不是任何类的成员函数
void printWidth(Box box)
{
/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
cout << "Width of box : " << box.width << endl;
}
// 程序的主函数
int main()
{
Box box;
BigBox big;
// 使用成员函数设置宽度
box.setWidth(10.0);
// 使用友元函数输出宽度
printWidth(box);
// 使用友元类中的方法设置宽度
big.Print(20, box);
getchar();
return 0;
}
友元成员
除了一般的函数可以作为某个类的友元外,另一个类的成员函数也可以作为某个类的友元。声明时需在友元成员函数前加上其所在的类名。定义友元成员的好处是两个类可以以某种方式相互合作、协调工作,完成某一任务。
另一个类的成员函数可以作为某个类的友元,只是声名友元函数时要加上成员函数所在的类名,称为友元成员。
声名:
friend 函数返回类型 类名::成员函数名(形参列表)
#include <iostream>
using namespace std;
class date;
class time
{
public:
time(int, int, int);
void display(date &);
private:
int hour;
int minute;
int sec;
};
class date
{
public:
date(int, int, int);
friend void time::display(date &);
private:
int month;
int day;
int year;
};
time::time(int h, int m, int s)
{
hour = h;
minute = m;
sec = s;
}
void time::display(date &d)
{
cout << d.month << "." << d.day << "." << d.year << endl;
cout << hour << ":" << minute << ":" << sec << endl;
}
date::date(int m, int d, int y)
{
month = m;
day = d;
year = y;
}
int main ()
{
time t1(10, 51, 56);
date d1(3, 20, 2018);
t1.display(d1);
return 0;
}