wordpress分类页面,杭州网络排名优化,厦门建设企业网站,请问的网站开发培训 有知道的吗这几天在复习数学考试#xff0c;都没有学C#xff0c;今天抽空来学一点。
什么是友元#xff1f;
友元是C中的一种关系友元发生在函数与类之间或者类与类之间友元关系是单向的#xff0c;不能传递
在具体讲解友元的性质之前#xff0c;我们先来看看一个程序#xff…这几天在复习数学考试都没有学C今天抽空来学一点。
什么是友元
友元是C中的一种关系友元发生在函数与类之间或者类与类之间友元关系是单向的不能传递
在具体讲解友元的性质之前我们先来看看一个程序这个程序是计算两点之间的距离
#include stdio.h
#include math.hclass Point
{
private:double x;double y;
public:Point(double x,double y){this-x x; //this指针指向当前的对象this-y y;}double getX(){return x;}double getY(){return y;}
};double func(Point p1,Point p2)
{double ret 0;ret (p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) (p1.getY() - p2.getY()) * (p1.getY() - p2.getY());ret sqrt(ret);return ret;
}int main()
{Point p1(1,2);Point p2(10,20);printf(p1(%f,%f)\n,p1.getX(),p1.getY());printf(p2(%f,%f)\n,p2.getX(),p2.getY());printf(|p1-p2| %f\n,func(p1,p2));return 0;
}上面代码运行结果为
p1(1.000000,2.000000)
p2(10.000000,20.000000)
|p1-p2| 20.124612看着也没什么大问题。下面我们来简单分析一下这个程序的实用性进行计算这个两点之间的距离时的代码为 ret (p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) (p1.getY() - p2.getY()) * (p1.getY() - p2.getY());进行了8次函数的调用这么简单的计算就需要调用8次函数这效率之慢在当初C诞生的时候是不被大多数人接受的大多数人用C编程习惯了都是可以直接这样调用的 ret (p1.x - p2.x) * (p1.x - p2.x) (p1.y - p2.y) * (p1.y - p2.y);然而C里面你就不能像上面那样直接调用类C里面可以是结构体或者数组的成员变量。因为它是private类型的变量。那么在C诞生的那个年代人们为了让C语言完全兼容C语言就在C中加入了友元的存在。那么友元的定义以及性质是什么样的呢
在类中以friend关键字声明友元类的友元可以是其他类或者具体的函数友元不是类的一部分友元不受类中访问级别的限制友元可以直接访问具体类的所有成员
直接将上面的代码修改一下看看
#include stdio.h
#include math.hclass Point
{
private:double x;double y;
public:Point(double x,double y){this-x x; //this指针指向当前的对象this-y y;}double getX(){return x;}double getY(){return y;}friend double func(Point p1,Point p2)
};double func(Point p1,Point p2)
{double ret 0;ret (p1.x - p2.x) * (p1.x - p2.x) (p1.y - p2.y) * (p1.y - p2.y);ret sqrt(ret);return ret;
}int main()
{Point p1(1,2);Point p2(10,20);printf(p1(%f,%f)\n,p1.getX(),p1.getY());printf(p2(%f,%f)\n,p2.getX(),p2.getY());printf(|p1-p2| %f\n,func(p1,p2));return 0;
}运行结果为
p1(1.000000,2.000000)
p2(10.000000,20.000000)
|p1-p2| 20.124612这样看来我们已经实现了直接访问类的私有成员变量。上面的代码func函数是Point类的友元可以直接访问Point的所有数据。但是这样做又不好为什么呢 友元的尴尬
友元是为了兼顾C语言的高效性而诞生的友元直接破坏了面向对象的封装性友元在实际产品中的高效是得不偿失的友元在现代软件工程中已经被逐渐遗弃
虽然基于以上的尴尬让友元这个功能在现代软件工程中很少被使用但是我们学习嘛肯定是都要学的哈哈~
友元需要注意的一些事项
友元关系不具备传递性类的友元可以是其他类的成员函数类的友元可以是某个完整的类所有的成员函数都是友元 下面我们再分析一个代码来看看友元的真实面目
#include stdio.hclass ClassC
{const char* n;
public:ClassC(const char* n){this-n n;}friend class ClassB;
};class ClassB
{const char* n;
public:ClassB(const char* n){this-n n;}void getClassCName(ClassC c){printf(c.n %s\n, c.n);}friend class ClassA;
};class ClassA
{const char* n;
public:ClassA(const char* n){this-n n;}void getClassBName(ClassB b){printf(b.n %s\n, b.n);}/*void getClassCName(ClassC c){printf(c.n %s\n, c.n);}*/
};int main()
{ClassA A(A);ClassB B(B);ClassC C(C);A.getClassBName(B);B.getClassCName(C);return 0;
}运行结果为
b.n B
c.n C分析代码知类B是C的友元类A是B的友元所以在B中可以直接访问C的私有成员变量在A中可以直接访问B的成员变量。 那么在A中能否直接访问C呢试验一下将上面的代码注释掉得部分恢复编译运行运行结果为
test.cpp: In member function ‘void ClassA::getClassCName(ClassC)’:
test.cpp:6: error: ‘const char* ClassC::n’ is private
test.cpp:44: error: within this context很显然A是不能访问C的私有成员的。
总结一下
友元是为了兼顾C语言的高效而诞生的友元直接破坏了面向对象的封装性友元关系不具备传递性类的友元可以是其他类的成员函数类的友元可以是某个完整的类
想获得各种学习资源以及交流学习的加我有我博客中写的代码的原稿 qq1126137994 微信liu1126137994 可以共同交流关于嵌入式操作系统C语言C语言数据结构等技术问题。