友元的概念
- 什么是友元
- 友元是C++中的一种关系
- 友元关系发生在函数与类之间或者类与类之间
- 友元关系是单项的,不能传递
友元的用法
-
在类中以friend关键字声明友元
-
类的友元可以是其他类或者是具体函数
-
友元不是类的一部分
-
友元不受类中访问级别的限制
-
友元可以直接访问具体类的所有成员
-
在类中用friend关键字对函数或类进行声明
#include <iostream>
#include <math.h>
#include <string>
using namespace std;
class Point{
private:
double x;
double y;
public:
Point(double x, double y)
{
this->x = x;
this->y = y;
}
double getX()
{
return x;
}
double getY()
{
return y;
}
friend double func(Point& p1, Point& p2);
//体验了一下,main()函数也可以当做friend
friend int main(int argc, char *argv[]);
};
double func(Point& p1, Point& p2)
{
double ret = 0;
//在C++初期,程序员都用C语言写代码,大家特别希望能够像p1.x一样调用,
//而不是像这样调用八次函数,效率降低。早期的程序员看到C++这样,所以就不用了。
//并且C++自诞生就背负着一个重要的责任就是兼容C语言,所以就出现了friend关键字。
// ret = (p1.getX() - p2.getX())*(p1.getX() - p2.getX()) +
// (p1.getY() - p2.getY())*(p1.getY() - p2.getY());
//有了friend关键字,就可以了无限制的访问类的私有成员
ret = (p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y);
ret = sqrt(ret);
return ret;
}
int main(int argc, char *argv[])
{
Point p1(1,2);
Point p2(10,20);
//检测main()函数被friend
cout << "p1(x,y) = "<< "(" << p1.x<< ","<< p1.y <<")"<< endl;
cout << "p1(x,y) = "<< "(" << p1.getX()<< ","<< p1.getY() <<")"<< endl;
cout << "p2(x,y) = "<< "(" << p2.getX()<< ","<< p2.getY() <<")"<< endl;
cout << "|(p1, p2)| = " << func(p1,p2) << endl;
return 0;
}
友元的尴尬
- 友元是为了兼顾C语言的高效而诞生的
- 友元的超能力直接破坏了面向对象的封装性
- 友元在实际产品中的高效是得不偿失的
- 友元在现在软件工程中已经逐渐被遗弃
注意事项
- 友元关系不具备传递性
- 类的友元可以是其他类的成员函数
- 类的友元可以是某个完整的类
- 所有的成员函数都是友元
#include <iostream>
#include <string>
using namespace std;
class classC
{
private:
const char* n;
public :
classC(const char* n)
{
this->n = n;
}
friend class classB;//B是C的友元,那么B就可以访问C的私有成员
};
class classB
{
private:
const char* n;
public :
classB(const char* n)
{
this->n = n;
}
void getClassCName(classC& c)
{
cout << "classC : " << c.n << endl;
}
friend class classA;//A是B的友元,那么A就可以访问B的私有成员
};
class classA
{
private:
const char* n;
public :
classA(const char* n)
{
this->n = n;
}
void getClassBName(classB& b)
{
cout << "classB : " << b.n << endl;
}
/*那是B是C的友元,A是B的友元,那么A是C的友元吗?实验测试:不是
void getClassCName(classC& c)
{
cout << "classB : " << c.n << endl;
}
*/
};
int main(int argc, char *argv[])
{
classA A("classA");
classC C("classC");
classB B("classB");
A.getClassBName(B);
B.getClassCName(C);
return 0;
}
小结
- 友元是为了兼顾C语言的高效而诞生的
- 友元直接破坏了面向对象的封装性
- 友元关系不具备传递性
- 类的友元可以是其他类的成员函数
- 类的友元课以是某个完整的类
Alipay
Wechat