《新编C++语言习题与解析》试读:4.1 基本知识点

第4章 友 元 本章学习要点  深入掌握友元函数的相关概念和使用方法。  深入掌握友元类的相关概念和使用方法。  灵活运用友元的相关知识进行综合程序设计。 4.1 基本知识点 4.1.1 友元函数 友元函数是一种特殊的函数,它需要在类体内进行说明,可以访问类的私有成员,但又不是类的成员函数。友元函数的说明格式如下: friend 数据类型 函数名(参数表) 其中,friend是说明友元函数的关键字。 归纳起来,友元函数是一种能够访问类中的私有成员的非成员函数。友元函数在定义上和调用上与普通函数一样。 友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。因此,只有在十分需要时才使用友元函数。 例如,分析下列程序的输出结果。 #include <iostream.h> #include <math.h> class TPoint { double x,y; //私有数据成员 public: TPoint(double a,double b) //构造函数 { x=a,y=b; cout << "点:(" << x << "," << y << ")" << endl; } friend double distance(TPoint &a,TPoint &b) //友元函数 { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } }; void main() { TPoint p1(2,2),p2(5,5); cout << "上述两点之间的距离:" //调用友元函数 << distance(p1,p2) << endl; } 在上述程序中,distance()是类TPoint的友元函数,在其中可以直接使用a.x等,由于x等是类TPoint的私有成员,所以在普通函数中是不能这样使用的。调用友元函数distance(p1,p2)时也不需要加上对象前缀。该程序执行结果如下: 点:(2,2) 点:(5,5) 上述两点之间的距离:4.24264 友元函数的一个重要特征是它可以是多个类的友元。 例如,编写一个程序,求一个点到直线的距离。 设计一个点类Point,它有两个私有数据成员x和y,表示点的坐标。另一个类为直线类Line,它有三个私有数据成员a、b和c,表示直线方程ax+by+c=0。这两个类中都说明了一个友元函数dist,用于计算一个点到直线的距离。点(x,y)到直线ax+by+c=0的距离d的计算公式如下: 求解程序如下: #include <iostream.h> #include <math.h> class Line; //提前说明 class Point { int x,y; public: Point(int x1,int y1) { x=x1; y=y1; } friend double dist(Line l,Point p); //友元函数声明 }; class Line { int a,b,c; public: Line(int a1,int b1,int c1) { a=a1; b=b1; c=c1; } friend double dist(Line l,Point p); //友元函数声明 }; double dist(Line l,Point p) //计算点对象p到直线对象l之间的距离 { double d; d=abs(l.a*p.x+l.b*p.y+l.c)/(sqrt(l.a*l.a+l.b*l.b)); return d; } void main() { Point p(10,10); Line l(2,4,-3); cout << "d=" << dist(l,p) << endl; } 上述程序中有两个类Point和Line,它们都说明了同一友元函数:friend double dist(Line l,Point p)。由于在Point类中说明时尚未定义Line类,所以需要在前面用class Line;语句进行提前说明。该程序的执行结果如下: d=12.7456 一个类A的成员函数f()可以作为另一个类B的友元函数,在这种情况下,必须先定义A类,并且在B类中说明友元函数f()时,要加上成员函数所在类的类名,即: class A { … 数据类型 f(参数表); … } class B { … friend 数据类型 A::f(参数表); … } 数据类型 A::f(参数表) { 函数体; } 4.1.2 友元类 除了前面讲过的友元函数外,友元还可以是一个类,即一个类可以作为另一个类的友元。当一个类作为另一个类的友元时,就意味着这个类的所有成员函数都是另一个类的友元函数。例如,以下程序说明类B是类A的友元类: class A { ... public: friend class B; //说明B是A的友元类 ... } 例如,有以下程序: #include <iostream.h> #include <math.h> class A { int x; public: A() {x=5;} friend class B; }; class B { public: void disp1(A tmp) {tmp.x++;cout << "disp1: x=" << tmp.x << endl; } void disp2(A tmp) {tmp.x--;cout << "disp2: x=" << tmp.x << endl; } }; void main() { A obj1; B obj2; obj2.disp1(obj1); obj2.disp2(obj1); } 上述程序中,类B是类A的友元类,类B包括两个成员函数,这两个成员函数可以当成类A自已的友元函数一样使用。该程序的执行结果如下: disp1:x=6 disp2:x=4 使用友元类时注意以下几点:  友元关系不能被继承。  友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。  友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的声明。

>新编C++语言习题与解析

新编C++语言习题与解析
作者: 李春葆 等
副标题: 新编C++语言习题与解析
isbn: 7302306206
书名: 新编C++语言习题与解析
页数: 323
定价: 38.00元
出版社: 清华大学出版社
出版年: 2013-5