c++ 之 友元函数和友元类
友元(friend)其实就是好朋友的意思,我是你的好朋友,我就能访问你的所有对象的私有或公有成员。
但是友元会破坏数据的封装性,所以使用要慎重。
一、友元函数
如果友元是普通函数,则称友元函数。它不是当前类的成员函数。
位置可以放在任何部分(私有部分或共有部分)。
例1:一个类的友元函数
#include<iostream>
#include<cmath>
using namespace std;
class Point{
private:
double x,y;
public:
Point(double xx = 0.0, double yy = 0.0);
void disp();
friend double dis(const Point &p1,const Point &p2); //友元函数
};
Point::Point(double xx, double yy){
x = xx;
y = yy;
}
void Point::disp(){
cout<<x<<","<<y<<endl;
}
double dis(const Point &p1,const Point &p2){ //不用Point::,因为它不是成员函数
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
int main()
{
Point p1(1,1),p2(2,2);
p1.disp();
p2.disp();
cout<<dis(p1,p2)<<endl;
return 0;
}
其中最好函数名不要用distance,原因链接:c++编译错误
例2:多个类的友元函数
#include<iostream>
#include<cmath>
using namespace std;
class Line;
class Point
{
private:
double x, y; //x,y 坐标
public:
Point(double x=0.0, double y=0.0);
void disp( );
friend double dist(const Point& p,const Line& l); //声明为Point的友元
};
Point::Point (double x, double y){
this->x = x;
this->y = y;
}
void Point::disp( ){
cout<<"点("<<x<<","<<y<<")";
}
class Line
{
private:
double a, b, c; //直线为ax+by+c=0的系数
public:
Line(double a=0.0, double b=0.0, double c=0.0);
void disp( );
friend double dist(const Point& p,const Line& l); //声明为Line的友元
};
Line::Line(double a, double b, double c){
this->a = a;
this->b = b;
this->c = c;
}
void Line::disp( ){
cout<<"线("<<a<<"x+"<<b<<"y+"<<c<<"=0)";
}
double dist(const Point& p,const Line& l){
return fabs(l.a*p.x+l.b*p.y+l.c)/sqrt(l.a*l.a+l.b*l.b);
}
int main(){
Point p1(1.0,2.0);
Line l1(3.0,4.0,5.0);
p1.disp();
l1.disp();
cout<<"距离为:"<<dist(p1,l1)<<endl;
return 0;
}
二、友元成员函数
#include<iostream>
#include<cmath>
using namespace std;
class Line;
class Point
{
private:
double x, y; //x,y 坐标
public:
Point(double x=0.0, double y=0.0);
void disp( );
double dist(Line l); //声明为Point的成员
};
Point::Point (double x, double y){
this->x = x;
this->y = y;
}
void Point::disp( ){
cout<<"点("<<x<<","<<y<<")";
}
class Line
{
private:
double a, b, c; //直线为ax+by+c=0的系数
public:
Line(double a=0.0, double b=0.0, double c=0.0);
void disp( );
friend double Point::dist(Line l); //声明为Line的友元
};
Line::Line(double a, double b, double c){
this->a = a; this->b = b; this->c = c;
}
void Line::disp( ){
cout<<"线("<<a<<"x+"<<b<<"y+"<<c<<"=0)";
}
double Point::dist(Line l){
return fabs(l.a*x+l.b*y+l.c)/sqrt(l.a*l.a+l.b*l.b);
}
int main()
{
Point p1(1.0,2.0);
Line l1(3.0,4.0,5.0);
p1.disp();
l1.disp();
cout<<"距离为:"<<p1.dist(l1)<<endl;
return 0;
}
三、友元类
#include<iostream>
#include<cmath>
using namespace std;
class Point
{
private:
double x, y; //x,y 坐标
public:
Point(double x=0.0, double y=0.0);
void disp( );
friend class ComputeTools; //声明为Point的友元类
};
Point::Point (double x, double y){
this->x = x;
this->y = y;
}
void Point::disp( ){
cout<<"点("<<x<<","<<y<<")";
}
class Line
{
private:
double a, b, c; //直线为ax+by+c=0的系数
public:
Line(double a=0.0, double b=0.0, double c=0.0);
void disp( ); // 输出私有变量的成员函数
friend class ComputeTools; //声明为Line的友元类
};
Line::Line(double a, double b, double c){
this->a = a;
this->b = b;
this->c = c;
}
void Line::disp( ){
cout<<"线("<<a<<"x+"<<b<<"y+"<<c<<"=0)";
}
class ComputeTools // Point and Line 的友元类
{
public:
static double distance(Point p1,Point p2); //重载点与点距离
static double distance(Point p,Line l); //重载点与直线距离
};
double ComputeTools::distance(Point p1,Point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double ComputeTools::distance(Point p,Line l){
return fabs(l.a*p.x+l.b*p.y+l.c)/sqrt(l.a*l.a+l.b*l.b);
}
int main(){
Point p1(1.0,2.0),p2(3.0,4.0);
Line l1(3.0,4.0,5.0);
p1.disp(); p2.disp();
cout<<"距离为:"<<ComputeTools::distance(p1,p2)<<endl;
p1.disp(); l1.disp();
cout<<"距离为:"<<ComputeTools::distance(p1,l1)<<endl;
return 0;
}