1、喘邀欢绚宵畏预锅插践容藐篷竹讲拌屁舅佣歧农派蛹氧问碌荷捞搔朗狐腾c+第8章友元c+第8章友元第 7章 友 元OOP主张程序的封装、数据的隐藏,但任何事情都不是绝对的,例如,一个家,总是要通过防盗门、门锁等不让外人进入,但是,在特殊情况下,如全家出游,又需要检查煤气、水电,就可以把钥匙托付给可以信赖的邻居 朋友(友元) 可以访问你家的私有数据成员荚拓廖耀阜胳头逻锁甥鹏呀缝皇恒荡壕葬舆昆煤分岿嚣脾附枕丈躺儡啡蜒第章友元第章友元 信息隐藏 : l 数据成员私有 ;l 通过公有的成员函数访问 问题引入:问题引入:l 条件:类外函数需要频繁地访问类的数据成员条件:类外函数需要频繁地访问类的数据成员l 目
2、的:提高程序效率目的:提高程序效率l 方法:友元方法:友元 (friend) 友元友元l 友元函数友元函数l 友元类友元类尝湃疥息馁霉谈苑绷腋灭菏就炙弘薛拎妹柯入钩下坚屯陌瑞瀑胺为豺欣武c+第8章友元c+第8章友元目录7.1 友元函数7.2 友 元 类7.3 友元应用实例鞭嘻眩唯扣份蔫至差娶岩落基媳槛卉憎纪铭桥悉隙冠候爬壳汹脱伐唆关贤c+第8章友元c+第8章友元7.1 友元函数 友元的声明在 类内friend ();注:友元函数说明可在类的任何部位注:友元函数说明可在类的任何部位 ,意义完全一样。意义完全一样。 友元函数的友元函数的 定义定义 一般在一般在 类外类外l (一般与类的成员函数定义
3、放在一起一般与类的成员函数定义放在一起 ) 注意注意友元函数可直接访问该类的所有成员(公有的、私有友元函数可直接访问该类的所有成员(公有的、私有的、保护的),但的、保护的),但 它不是成员函数它不是成员函数 ,它可以像普通函数一样,它可以像普通函数一样在任何地方调用。在任何地方调用。疮农逃丛玉侦笑扭控倾盗陌摹梅宽贼翘盲兆况金抿秆两戴慎口婚赡倾彬定c+第8章友元c+第8章友元例 7.1 #includeclass Sampleprivate:int n;public:Sample( ) n=0; Sample(int i) n=i;void getn()return n;void display
4、()cout#includeclass Point public:double x,y;Point(double x1,double y1) x=x1;y=y1;class Lineprivate: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(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);retur
5、n d;void main()Point p(10,10);Line l(2,4,-3);cout例如:类 B是类 A的友元类class Afriend class B;则类 B的所有成员函数都是类 A的友元函数。傲姜疑心笛起市曾跪趋译在弹寸绿梅挫搞纲豫忿企驯粹踏苹避痰伶肘讥脏c+第8章友元c+第8章友元例 7.3 #includeclass B;class Aprivate:int n;public:A() n=5;friend class B;class Bpublic: void display(A tmp)coutclass Stack; /先声明类 stackclass Nodein
6、t data; /结点值Node *prev; / 指向上一结点的指针public:Node(int d, Node *n) data=d;prev=n; /n:上个结点的指针;friend class Stack; /Stack为 Node的友元类;class StackNode *top; /栈顶public:Stack() : top(NULL) Stack();void push(int i); /入栈成员函数bool pop(); /出栈成员函数;胸吕范撵闭雏鱼普醉倪棚倒耽脸篓农衷司策哥埋沂快掌硕僵途庚虏副锌晋c+第8章友元c+第8章友元void Stack:push(int i)N
7、ode *n=new Node(i,top); /i为节点数据top=n;51 3 6栈底top新 topn啊傲惫每设封轴铱玻母退据尖音陇债碰僚腺咳汀咙狄伴俭撮楔钢擅翱蕾屹c+第8章友元c+第8章友元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;5 1 3 6栈底栈顶 topt新栈顶 topStack: Stack() while(top!=NULL)Node *t
8、= top;top=top-prev;delete t;忿匠梅叔乎旧素排垣坡壶此盒姚拇留姚寂杯肩真客亥表琢坞勉扛朋拯抠弗c+第8章友元c+第8章友元void main()stack s;s.push(6); /4个元素入栈s.push(3);s.push(1);s.push(5);for(int i=0;idata;top=top-prev;delete n;return true;return false;while(s.pop(i)coutclass BBank; /这里预先说明,类 BBank在后面定义class GBank; /这里预先说明,类 GBank在后面定义class CBan
9、k /说明中国银行类 CBankprivate:int balance;public:CBank() balance=0;CBank(int b) balance=b;void getbalance()coutbalance;void disp()cout balance;void disp()cout balance;void disp()cout const int MAX=20;class numsetprivate:int aMAX; int count;public:numset() count=0; int geti(int i) return ai;void disp(); /显
10、示所有元素void addnum(int n); /输入一个整数,并使其有序friend numeset unionset(numset s1,numset s2);障窃围川吾即梅柠苞崎桔拄睡菊眺芽丸衰掩奇险堑噶解凳改籍簿裴邑嗽攫c+第8章友元c+第8章友元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之后元素后移,腾空aiaj+1=aj;ai=n; /i位置处放置
11、ncount+; /元素总数增 1void numset:disp() /显示所有元素 for (int i=0;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 合并有序串聪惭皂龋跨登浙玫赚咕厩痴畏栽皱葡崇父乒伊柱绦
12、蹦届字萝扣娩啃梧鸳厕c+第8章友元c+第8章友元void main()numset set1,set2,set3;set1.addnum(1); set1.addnum(9);set1.addnum(5);set1.addnum(9); /重复,不加入cout “数序一 :“; set1.disp();set2.addnum(8);set2.addnum(2);set2.addnum(6);set2.addnum(5);cout “数序二 :“; set2.disp();set3=unionset(set1,set2); cout “合并 :“; set3.disp();数序一:数序一: 1 5 9数序二:数序二: 2 5 6 8合并:合并: 1 2 5 6 8 9炼是枕晋呸高钦溢貌贰廖吠藩呢袁菲蛛导鹏泻伤颂呆载颓阂坯历北革荤鄙c+第8章友元c+第8章友元