第7章 友 元.ppt_第1页
第7章 友 元.ppt_第2页
第7章 友 元.ppt_第3页
第7章 友 元.ppt_第4页
第7章 友 元.ppt_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第7章 友 元,OOP主张程序的封装、数据的隐藏,但任何事务都不是绝对的,例如,一个家,总是要通过防盗门、门锁等不让外人进入,但是,在特殊情况下,如全家出游,又需要检查煤气、水电,就可以把钥匙托付给可以信赖的邻居 朋友(友元)可以访问你家的私有数据成员,信息隐藏: 数据成员私有; 通过公有的成员函数访问 问题引入: 条件:类外函数需要频繁地访问类的数据成员 目的:提高程序效率 方法:友元(friend) 友元 友元函数 友元类,目录,7.1 友元函数 7.2 友 元 类 7.3 友元应用实例,7.1 友元函数,友元的声明在类内 friend (); 注:友元函数说明可在类的任何部位(publi

2、c区,protected区)意义完全一样。 友元函数的定义一般在类外 (一般与类的成员函数定义放在一起) 注意 友元函数可直接访问该类的所有成员(公有的、私有的、保护的),但它不是成员函数,它可以像普通函数一样在任何地方调用。,例7.1,#include class Sample private: int n; public: Sample( ) n=0; Sample(int i) n=i; void getn()return n; void display()coutn=nendl; friend Sample square(Sample); /友元函数说明 ; Sample square

3、(Sample x) int tmp=x.n*x.n; return Sample(tmp); void main() Sample a(5),b; b=square(a); b.display(); ,/如果该函数没有定义为友元: Sample square(Sample x) int tmp=x.getn()*x.getn(); return Sample(tmp); 结果如下: n=25,例7.2 求一个点到直线的距离。,点类Point,点坐标用两个数据成员x和y表示(因为要在类外使用,所以设计为公有的)。 直线类Line,直线方程 为ax2+bx+cx=0,系数用三个私有数据成员a、b

4、和c表示 设计一个函数dist(参数为Point和Line)计算一个点(x,y)到直线ax2+bx+cx=0的距离d公式如下。,#include #include class Point public: double x,y; Point(double x1,double y1) x=x1;y=y1; ; class Line private: double a,b,c; public: Line(double a1,double b1,double c1) a=a1; b=b1; c=c1; friend double dist(Line l,Point p); ; double dist(

5、Line l,Point p) 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); coutd=dist(l,p)endl; ,7.2 友 元 类friendclass,定义:类A定义中用关键词friend说明类B friend class 例如:类B是类A的友元类 class A friend class B; ; 则类B的所有成员函数都是类A的友元函数。,例7.3,#include class A private:

6、 int n; public: A() n=5; friend class B; ; class B public: void display(A tmp) cout“n=”tmp.nendl; /B的成员函数访问了A的私有数据 ; void main() A a; B b; b.display(a); ,例74实现一个栈后进先出,要求: 实现栈的压入(入栈)和弹出(出栈)。 设计(用链表实现栈): 结点类node,它包含结点值data和指向上一个结点的指针prev; 栈类stack,它包含栈的头指针top。 生成的链式栈如图71所示,#include class Stack; /先声明类st

7、ack class Node int data; /结点值 Node *prev; / 指向上一结点的指针 public: Node(int d, Node *n) data=d; prev=n; /n:上个结点(栈顶)的指针 ; friend class Stack; /Stack为Node的友元类 ; class Stack Node *top; /栈顶 public: Stack() : top(NULL) Stack(); void push(int i); /入栈成员函数 bool pop(int ,void Stack:push(int i) Node *n=new Node(i,

8、top); /i为节点数据 top=n; ,栈底,top,新top,n,int Stack:pop( ) Node *t=top; /t指向栈顶结点 if (top!=NULL) top=top-prev /top后退一个结点 int c=t-data; /c取原栈顶结点的data值 delete t; /释放栈顶结点 return c; return 0; ,栈底,栈顶top,t,Stack: Stack() while(top!=NULL) Node *t = top; top=top-prev; delete t; ,void main() stack s; s.push(6); /4个

9、元素入栈 s.push(3); s.push(1); s.push(5); for(int i=0;i4;i+) cout s.pop() “ ”; cout endl; ,栈底,改进,法1:增加isnull() 无需知道栈内确切的元素个数,只要判别不为空,就可以出栈! bool Stack:isnull() if(top=NULL) return true; else return false; while(!s.isnull() couts.pop()“ ”; ,法2:修改pop,带引用参数,并修改返回值为bool类型 bool Stack:pop(int ,友元friend小结,友元的声

10、明在类内,定义一般在类外 包括(友元函数、友元类) class A friend int f(int a); /友元函数 friend class B; /友元类 int f(int a) Class B . 友元的单向性和非传递性 单向性:B是A的友元类,并不意味A也是B的友元 非传递性:是B的友元类, B是A 的友元类,并不意味C是A的友元类 友元函数vs.成员函数,类A的友元函数f 它不是A的成员函数,但有权访问和调用A的所有私有及保护成员 定义一般在类外,但也可以在类内,类A的友元类B B的任一函数都有权访问和调用A的所有成员,包括私有和保护的成员 一定要在类外定义,7.3友元应用实例

11、例7.5 银行(自学),设计三个类 中国银行类Cbank 工商银行类Bbank 农业银行类GBank。 每个类都包含 一个私有数据balance:存放储户在该行的存款数, 一个友元函数total:计算储户在三家银行总存款数,图7.2 类结构,程序,#include class BBank; /这里预先说明,类BBank在后面定义 class GBank; /这里预先说明,类GBank在后面定义 class CBank /说明中国银行类CBank private: int balance; public: CBank() balance=0; CBank(int b) balance=b; vo

12、id getbalance() coutbalance; void disp() cout中国银行存款数:balanceendl; friend void total(CBank,BBank,GBank); ;,class BBank /说明工商银行类Bbank private: int balance; public: BBank() balance=0; BBank(int b) balance=b; void getbalance() cout balance; void disp() cout 工商银行存款数: balance endl; friend void total(CBank

13、,BBank,GBank); ;,class GBank /说明农业银行类GBank private: int balance; public: GBank() balance=0; GBank(int b)balance=b; void getbalance() cout balance; void disp() cout 农业银行存款数: balance endl; friend void total(CBank,BBank,GBank); ;,void total(CBank A,BBank B,GBank C) cout 总存款数: A.balance+B.balance+C.bala

14、nce endl; void main() CBank X(100); BBank Y; GBank Z; X.disp();Y.disp();Z.disp(); Y.getbalance(); Z.getbalance(); total(X,Y,Z); ,7.3友元应用实例例7.6合并排序,设计类 numset:输入一个整数数序,并按从小到大排列且不包含相同元素。 设计友元函数unionset:合并两个有序数序,#include const int MAX=20; class numset private: int aMAX; int count; public: numset() coun

15、t=0; int geti(int i) return ai; void disp(); /显示所有元素 void addnum(int n); /输入一个整数,并使其有序 friend numeset unionset(numset s1,numset s2); ,void numset:addnum(int n) /添加一个元素n,并使之有序 int i=0,j; while (i=ai ) i+; /找到n应放的位置i if (n=ai-1) return; /相同的元素不添加 for (j=count;j=i;j- -) /ai之后元素后移,腾空ai aj+1=aj; ai=n; /i

16、位置处放置n count+; /元素总数增1 void numset:disp() /显示所有元素 for (int i=0;icount;i+) cout ai ; cout endl; ,/numset的成员函数,numset unionset(numset s1,numset s2) numset s; int i=0,j=0; int v1,v2; while (iv2) s.addnum(v2); j+; else s.addnum(v1); i+; j+; /end if /end while,while (is1.count) /s1未排完 v1=s1.geti(i); s.addnum(v1); i+; while (js2.count) /s2未排完 v2=s2.geti(j); s.addnum(v2); j+; return s; ;/end uninoset,/友元函数uninonset合并有序串,void main(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论