1、第五章特殊函数和组员第五章特殊函数和组员5.1对象组员初始化对象组员初始化类对象能够做其它类数据组员,称为类对象能够做其它类数据组员,称为对象组员。对象组员。如:如:classA类名类名1组员组员1;类名类名2组员组员2;当当A A类产生对象时要初始化类产生对象时要初始化A A全部组员,所以会调用全部组员,所以会调用A A类类 函数。函数。结构结构1第1页A A类结构函数定义以下:类结构函数定义以下:A:A(A:A(参数参数0)0):组员组员1(1(参数参数1)1),组员组员2(2(参数参数2)2),组员组员n(n(参数表参数表n)n)/其它操作其它操作 注:假如初始化列表某项参数表为空,则列
2、表中对应项能够省注:假如初始化列表某项参数表为空,则列表中对应项能够省略。略。2第2页如有:如有:classdateintyear,month,day;public:;classstudentintnum;stringname;datebirthday;public:;则则student类结构函数形式为:类结构函数形式为:student(intn,strings,dated):num(n),name(s),birthday(d)3第3页若对象若对象B是类是类A子对象,则在建立子对象,则在建立A类对象时:类对象时:执行执行B结构函数结构函数(初始化类中其它组员)(初始化类中其它组员)结构结构次序
3、次序执行执行B结构函数结构函数(初始化(初始化B数据组员)数据组员)执行执行B析构函数析构函数执行执行A析构函数析构函数析构析构次序次序注意:注意:1)A产生对象时,先调用对象组员结构函数,初始化产生对象时,先调用对象组员结构函数,初始化对象组员,然后才执行对象组员,然后才执行A结构函数,对象组员初始化次序与结构函数,对象组员初始化次序与这些对象在类这些对象在类A中说明次序,中说明次序,与它们在初始化列表中次序无与它们在初始化列表中次序无关。关。4第4页注意:注意:2)A类结构函数中未给出组员对象初始化,组员对象产生时类结构函数中未给出组员对象初始化,组员对象产生时调用无参结构函数,若此时组员
4、所在类中没有没有参结构函数则报调用无参结构函数,若此时组员所在类中没有没有参结构函数则报错!错!5第5页找出下面程序错误找出下面程序错误,更正后分析程序结果更正后分析程序结果(lt5_1b.cpp)(lt5_1b.cpp)class A int x1,y1;class A int x1,y1;public:public:A(int c,int d)A(int c,int d)x1=c;y1=d;coutA x1=c;y1=d;coutA结构!结构!x1y1endl;x1y1endl;class B A a;int x2,y2;class B A a;int x2,y2;public:publi
5、c:B()coutB B()coutB默认结构!默认结构!;B(int c=0,int d=0)B(int c=0,int d=0)x2=c;y2=d;coutB x2=c;y2=d;coutB结构!结构!x2y2endl;x2y2endl;void main()void main()B b;B b;A()coutAA()coutA默认结构默认结构endl;endl;Bb(1,2);B(intc,intd,intx,inty):a(x,y)Bb(1,2,10,100);6第6页练习:给出程序运行结果(练习:给出程序运行结果(lt5_1.cpp)#includeusingnamespacestd
6、;classPointintx,y;public:Point():x(0),y(0)Point(inta,intb):x(a),y(b)cout结构结构:x,yendl;classRectanglePointa;Pointb;public:Rectangle(intx,inty,intm,intn):a(x,y),b(m,n);voidmain()Rectanglea(1,1,5,5);b(m,n),a(x,y)7第7页const组员和引用组员初始化组员和引用组员初始化数据组员不能在定义时初始化数据组员不能在定义时初始化数据组员操作语句必须放在组员函数中数据组员操作语句必须放在组员函数中引用组
7、员不能初始化为常量引用引用组员不能初始化为常量引用const组员和引用组员组员和引用组员必须在结构函数初始化列表中初始化必须在结构函数初始化列表中初始化(lt5_1c.cpp)初始化列表形式结构函数:初始化列表形式结构函数:A:A(参数(参数0):组员组员1(参数(参数1),组员组员2(参数(参数2)9第9页usingnamespacestd;classexampleconstintnum;intdata;int&ref;public:example(intn,intf):num(n),data(f),ref(data)cout结构结构.endl;voidshow()cout对象中数据是:对象
8、中数据是:num,data,refendl;voidmain()intx=1,y=2;examplea(x,y);a.show();10第10页定义时使用了定义时使用了static,则组员为静态组员,则组员为静态组员5.2静态组员静态组员说明:说明:1 1)静态数据组员必须在类体外按照以下格式:)静态数据组员必须在类体外按照以下格式:类型类型 类名类名:静态组员名静态组员名=值;值;进行初始化,不可在结构函数中初始化进行初始化,不可在结构函数中初始化11第11页classTeststaticintx;intn;public:Test()Test(inta,intb)x=a;n=b;static
9、intfunc()returnx;staticvoidsfunc(Test&r,inta)r.n=a;intGetn()returnn;intTest:x=25;静态数据组员初始化静态数据组员初始化12第12页4、静态组员是类组员不是对象组员、静态组员是类组员不是对象组员2 2、staticstatic组员全部者是组员全部者是类类,被该类全部对象所共有,被该类全部对象所共有,全部对象均可访问静态组员全部对象均可访问静态组员 。静态组员依然遵照静态组员依然遵照public,private,protected访问准则。访问准则。3 3、静态组员不依赖于对象而存在、静态组员不依赖于对象而存在 对象不
10、存在时静态组员已存在对象不存在时静态组员已存在5、静态组员函数静态组员函数没有没有this指针指针,不可直接使用非静态组员,不可直接使用非静态组员,必须必须经过对象(或者指向对象指针)经过对象(或者指向对象指针)使用非静态组使用非静态组员。员。13第13页classTeststaticintx;intn;public:Test()Test(inta,intb)x=a;n=b;staticintfunc()returnx;staticvoidsfunc(Test&r,inta)r.n=a;intGetn()returnn;intTest:x=25;类中类中任何函数任何函数都能够都能够访问静态组员
11、。访问静态组员。静态组员函数不能静态组员函数不能直接访问非静态数直接访问非静态数据组员,能够经过据组员,能够经过对象来访问。对象来访问。(inta)n=a;error:illegalreferencetodatamemberTest:ninastaticmemberfunction.14第14页7、未定义对象时,能够经过类使用静态组员按以、未定义对象时,能够经过类使用静态组员按以下格式:下格式:类名类名:静态数据组员名静态数据组员名类名类名:静态组员函数静态组员函数();6、静态组员函数不能说明为虚函数(第、静态组员函数不能说明为虚函数(第8章)章)15第15页classTestintn;pu
12、blic:Test()Test(inta,intb)x=a;n=b;staticintfunc()returnx;staticvoidsfunc(Test&r,inta)r.n=a;intGetn()returnn;intTest:x=25;voidmain()coutTest:func();经过类使用静态经过类使用静态组员函数组员函数staticintx;coutTest:x();经过类使用静经过类使用静态组员函数或态组员函数或者数据组员者数据组员16第16页classTestintn;staticintx;public:Test()Test(inta,intb)x=a;n=b;static
13、intfunc()returnx;staticvoidsfunc(Test&r,inta)r.n=a;intGetn()returnn;intTest:x=25;voidmain()Testb,c;b.sfunc(b,58);coutb.Getn();coutb.func();coutc.func();Testa(24,56);couta.func()b.func()c.func()endl;58252524242417第17页classTestintn;staticintx;public:Test()Test(inta,intb)x=a;n=b;staticintfunc()n=x+1;re
14、turnx;staticvoidsfunc(Test&ref,inta)ref.n=a;intGetn()returnn;找出下面类定义中错误,并说明原因找出下面类定义中错误,并说明原因intTest:x=100;静态组员函数静态组员函数不能直接访问不能直接访问非静态数据组非静态数据组员员静态数据组员必静态数据组员必须进行初始化须进行初始化18第18页1,静态组员函数与类名连用,可经过对象使用,静态组员函数与类名连用,可经过对象使用class teststatic int x;int n;public:test(int a=0,int b=0)x=a;n=b;static int func()
15、return x;int getn()return n;int test:x=25;void main()couttest:func()endl;test b;cout b.func()endl;与类名连用与类名连用经过对象使用经过对象使用19第19页2,在没有建立对象之前,静态组员已经存在,在没有建立对象之前,静态组员已经存在class teststatic int x;int n;public:test(int a=0,int b=0)x=a;n=b;static int func()return x;int getn()return n;int test:x=25;void main()
16、couttest:func()endl;test b,c;cout b.func()endl;20第20页3,静态组员是,静态组员是类类组员组员不是对象不是对象组员组员class teststatic int x;int n;public:test(int a=0,int b=0)x=a;n=b;static int func()return x;int getn()return n;int test:x=25;void main()couttest:func()endl;test b,c;cout b.func()endl;21第21页4,静态组员被类全部对象共享,静态组员被类全部对象共享c
17、lass teststatic int x;int n;public:test(int a=0,int b=0)x=a;n=b;static int func()return x;int getn()return n;int test:x=25;void main()couttest:func()endl;test b,c;cout b.func()c.func()endl;22第22页5,静态组员函数不可使用非静态组员,静态组员函数不可使用非静态组员class teststatic int x;int n;public:test(int a=0,int b=0)x=a;n=b;static
18、int func()return n;int test:x=25;void main()couttest:func()endl;test b,c;cout b.func()c.func()endl;错误错误23第23页特点:特点:一旦定义一直存在于内存中,一旦定义一直存在于内存中,直到程序结束才释放直到程序结束才释放复合语句(复合语句(用括起来多条语句用括起来多条语句)内定义对象只在复)内定义对象只在复合语句内有效,复合语句执行完成,对象释放合语句内有效,复合语句执行完成,对象释放内存。内存。5.2静态组员静态组员-静态对象静态对象静态对象是由静态对象是由static申明类对象申明类对象24第
19、24页classtestintn;public:test(inti)n=i;cout结构结构:nendl;test()cout析构析构:nendl;intgetn()returnn;voidinc()+n;voidmain()cout循环开始循环开始endl;for(inti=0;i2;i+)couti=i时时:endl;testb(3);b.inc();coutb.n=b.getn()endl;cout循环结束循环结束endl;coutmain结束结束endl;bi=0时时:3 4循环开始循环开始结构结构:3b=4析构析构4i=0时时:bi=1时时:3 425第25页classtestint
20、n;public:test(inti)n=i;cout结构结构:nendl;test()cout析构析构:nendl;intgetn()returnn;voidinc()+n;voidmain()cout循环开始循环开始endl;for(inti=0;i2;i+)couti=i时时:endl;testb(3);b.inc();coutb.n=b.getn()endl;cout循环结束循环结束endl;coutmain结束结束endl;statictestb(3);bi=0时时:3 4循环开始循环开始结构结构:3b=4i=0时时:i=1时时:i=1时时:5b=5循环结束循环结束main结束结束析
21、构析构526第26页voidmain()cout循环开始循环开始endl;for(inti=0;i2;i+)couti=i时时:endl;testb(3);b.inc();coutb.n=“b.getn()endl;cout循环结束循环结束endl;coutmain结束结束endl;voidmain()cout循环开始循环开始endl;for(inti=0;i2;i+)couti=i时时:endl;statictestb(3);b.inc();coutb.n=“b.getn()endl;cout循环结束循环结束endl;coutmain结束结束endl;27第27页注:静态对象结构函数与析构函
22、数调特点:注:静态对象结构函数与析构函数调特点:1、结构函数在代码执行过程中,第一次碰到它变量定义时被调、结构函数在代码执行过程中,第一次碰到它变量定义时被调用,但直到整个程序结束之前仅调用一次。用,但直到整个程序结束之前仅调用一次。2、析构函数在整个程序退出之前被调用,一样也只调用一次。、析构函数在整个程序退出之前被调用,一样也只调用一次。即:即:碰到定义则调用结构函数,碰到定义则调用结构函数,程序结束调用析构函数程序结束调用析构函数结构函数只调用一次,结构函数只调用一次,析构函数也只调用一次析构函数也只调用一次28第28页课程回顾2一个一个const对象只能访问对象只能访问组员函数。组员函
23、数。3.设类设类Test中存在组员中存在组员staticintx,则以下哪种初始化方式,则以下哪种初始化方式是正确(是正确()A.Test:intx=25;B.intx=25;C.intTest:x=25;D.intTestx=25;constC4.类类A中存在公有静态数据组员中存在公有静态数据组员x,设,设a和和b是类是类A两个对象,两个对象,在执行在执行a.x=10之后,之后,b.x值为值为()A.未初始化未初始化B.等于等于a.xC.等于等于0D.随机随机B1.若类组员函数用关键字若类组员函数用关键字static进行修饰,这么组员函数称为进行修饰,这么组员函数称为。静态组员函数静态组员函
24、数29第29页5.关于类静态组员函数描述错误是关于类静态组员函数描述错误是()A.在创建对象前不存在在创建对象前不存在B.能够被非静态组员函数访问能够被非静态组员函数访问C.能够直接被静态组员函数访问能够直接被静态组员函数访问D.不是对象组员不是对象组员A30第30页5.3友元函数友元函数友元提供给了不一样类或者对象组员函数之间、类组员函数与普友元提供给了不一样类或者对象组员函数之间、类组员函数与普通函数之间进行数据共享机制。也就是说,经过友元,一个普通函通函数之间进行数据共享机制。也就是说,经过友元,一个普通函数或者类组员函数能够访问到封装于另一个类中数据,这相当于给数或者类组员函数能够访问
25、到封装于另一个类中数据,这相当于给类封装开了一个小孔,经过它能够看到类内部一些属性。类封装开了一个小孔,经过它能够看到类内部一些属性。假如友元是普通函数或者类组员函数,则称为假如友元是普通函数或者类组员函数,则称为友元函数友元函数。友元函。友元函数是拥有组员函数一切权利非组员函数。也就是说,友元函数数是拥有组员函数一切权利非组员函数。也就是说,友元函数不是不是类组员函数类组员函数,但能够像组员函数一样直接访问类,但能够像组员函数一样直接访问类私有私有组员。组员。假如友元是一个类,则称为假如友元是一个类,则称为友元类友元类,友元类全部组员函数都为友元类全部组员函数都为友元函数友元函数。32第32
26、页友元三种形式:友元三种形式:1、普通函数作一个类友元、普通函数作一个类友元2、将、将a类组员函数作类组员函数作b类友元类友元3、将一个类、将一个类a作为另一个类作为另一个类b友元友元33第33页一个友元一个友元类类/函数函数/组员函数组员函数能够能够经过对象使用另一个类经过对象使用另一个类私有私有组员组员。友元函数能够访问友元函数能够访问对象私有组员,公有组员和保护组员对象私有组员,公有组员和保护组员。友元能够是一个类或函数。友元能够是一个类或函数。友元需经过对象、对象引用、对象指针来使用类友元需经过对象、对象引用、对象指针来使用类组员。组员。34第34页在类外对在类外对fun函数进行定义,
27、函数进行定义,此时此时fun函数不是类组员函数函数不是类组员函数友元申明能够在类友元申明能够在类private和和public部分部分普通友元函数能够经过普通友元函数能够经过对象、对象引用、对象指针对象、对象引用、对象指针使用使用对象对象私有组员私有组员。一、普通函数作一个类友元一、普通函数作一个类友元在在类体内类体内用用friend对普通函数对普通函数fun进行进行申明申明,则则fun成成为类友元函数。为类友元函数。35第35页在类体内需要对友元函数进行申明在类体内需要对友元函数进行申明classpointdoublex,y;public:point(doublexi,doubleyi)x=
28、xi;y=yi;frienddoubledist(point&p1,point&p2);doubledist(point&p1,point&p2)doubledx=p1.x-p2.x;doubledy=p1.y-p2.y;returnsqrt(dx*dx+dy*dy);在类中申明,在类中申明,但不是组员但不是组员函数函数point&p1,point&p2友元函数不是类组员函友元函数不是类组员函数,没有数,没有this指针,所指针,所以必须用对象或者引用以必须用对象或者引用或者对象指针做参数。或者对象指针做参数。point:dist(point&p1,point&p2)36第36页class p
29、ointdouble x,y;public:point(double m,double n)x=m;y=n;friend double dist(point&p1,point&p2);double dist(point&p1,point&p2)double dx=p1.x-p2.x;double dy=p1.y-p2.y;return sqrt(dx*dx+dy*dy);void main()point p1(1.1,2.2),p2(3.3,4.4);cout dist(p1,p2)endl;37第37页引用做形参和对象做形参区分是什么?引用做形参和对象做形参区分是什么?引用做形参和对象做形参
30、区分是什么?引用做形参和对象做形参区分是什么?对象做形参,形参对象对象做形参,形参对象对象做形参,形参对象对象做形参,形参对象 内存,内存,内存,内存,会引发会引发会引发会引发 函数函数函数函数调用调用调用调用 引用做形参,形参引用做形参,形参引用做形参,形参引用做形参,形参 内存,内存,内存,内存,复制结构复制结构复制结构复制结构函数函数函数函数对象做形参,形参改变对象做形参,形参改变对象做形参,形参改变对象做形参,形参改变 引发实参改变。引发实参改变。引发实参改变。引发实参改变。引用做形参,形参改变引用做形参,形参改变引用做形参,形参改变引用做形参,形参改变 引发实参改变引发实参改变引发实
31、参改变引发实参改变指针做形参也可实现,注意其形式什么?指针做形参也可实现,注意其形式什么?指针做形参也可实现,注意其形式什么?指针做形参也可实现,注意其形式什么?复制结构复制结构不分配不分配不分配不分配分配分配分配分配不调用不调用不调用不调用会会会会不会不会不会不会38第38页class pointdouble x,y;public:point(double m,double n)x=m;y=n;friend double dist(point&p1,point&p2);double dist(point&p1,point&p2)double dx=p1.x-p2.x;double dy=p1
32、.y-p2.y;return sqrt(dx*dx+dy*dy);void main()point p1(1.1,2.2),p2(3.3,4.4);cout dist(p1,p2)*-&39第39页假定假定f()是类是类A中组员函数中组员函数能够在类能够在类B中申明中申明将类将类A组员函数组员函数f()申明为类申明为类B友元友元申明函数申明函数f时需限定该函数时需限定该函数f是类是类A组员函数组员函数并在并在f中访问中访问B组员时,需经过对象、引用、指针来进行访组员时,需经过对象、引用、指针来进行访问。问。二、二、A A类组员函数作类组员函数作B B类友元类友元classAvoidf(B&);
33、;classBfriendvoidA:f(B&);;将将A类组员函类组员函数数f说明为该说明为该类友元类友元40第40页classTwo;classOneintx;public:One(inta):x(a);intGetx()returnx;voidfunc(Two&);/不完全类申明不完全类申明(Two),方便在类方便在类One中引用中引用Two直接使用类直接使用类Two私有组员私有组员classTwointy;public:Two(intb):y(b)intGety()returny;friendvoidOne:func(Two&);voidOne:func(Two&r)r.y=x;错误:
34、不完全申明类错误:不完全申明类不能实例化。不能实例化。不能存取没有完全申不能存取没有完全申明类组员。明类组员。41第41页#includeusingnamespacestd;classTwo;classOneintx;public:One(inta):x(a);intGetx()returnx;voidfunc(Two&);classTwointy;public:Two(intb):y(b)intGety()returny;friendvoidOne:func(Two&);voidOne:func(Two&r)r.y=x;voidmain()Oneobj1(5);Twoobj2(8);cout
35、obj1.Getx(),obj2.Gety()endl;obj1.func(obj2);cout调用友元组员函数后调用友元组员函数后:endl;coutobj1.Getx(),obj2.Gety()endl;5,8调用友元组员函数后:调用友元组员函数后:5,542第42页在类在类B中申明类中申明类A为为B友元格式:友元格式:classBfriendclassA二、将一个类二、将一个类A A说明为另一类说明为另一类B B友元友元注:假如类注:假如类A为类为类B友元,则类友元,则类A中中全部组员函数均居于友元全部组员函数均居于友元函数功效函数功效。43第43页classTwo;classOnein
36、tx;public:One(inta):x(a);intGetx()returnx;voidfunc(Two&);classTwointy;public:Two(intb):y(b)intGety()returny;voidOne:func(Two&r)r.y=x;friendvoidOne:func(Two&);friendclassOne;思索:思索:此申明能不能省此申明能不能省略?略?思索:思索:func函数定义函数定义可否放在类可否放在类Two定义前?定义前?不能不能不能不能voidmain()Oneobj1(5);Twoobj2(8);coutobj1.Getx(),obj2.Get
37、y()endl;obj1.func(obj2);cout调用友元组员函数后调用友元组员函数后:endl;coutobj1.Getx(),obj2.Gety()endl;44第44页总结:总结:1、友元、友元申明与访问控制无关申明与访问控制无关。在在private和和public后申明效果相同。后申明效果相同。2、友元关系是、友元关系是不能传递不能传递。若若A是是B友元,友元,B是是C友元,友元,A不能自动称为不能自动称为C友元。友元。注意:此时哪个类能访问哪个类组员?注意:此时哪个类能访问哪个类组员?3、友元关系是、友元关系是单向单向。若若A是是B友元,友元,B不一定是不一定是A友元。友元。4
38、5第45页友元三种形式:友元三种形式:1,普通函数作一个类友元,普通函数作一个类友元2,a类组员函数作类组员函数作b类友元类友元3,a类作为类作为b类友元类友元课程回顾课程回顾46第46页1.以下关于友元描述错误是(以下关于友元描述错误是()A.组员函数不可作友元组员函数不可作友元B.类能够作友元类能够作友元C.普通函数能够作友元普通函数能够作友元D.静态函数能够作友元静态函数能够作友元2.友元函数能够存取类友元函数能够存取类_、公有组员和保护组员。、公有组员和保护组员。3.在在C+中,即使友元提供了类之间数据进行访问一个方中,即使友元提供了类之间数据进行访问一个方式,但它破坏了面向对象程序设
39、计式,但它破坏了面向对象程序设计_特征。特征。4.假如类假如类A被申明成类被申明成类B友元,则友元,则()A.类类A组员即类组员即类B组员组员B.类类B组员即类组员即类A组员组员C.类类A组员函数不得访问类组员函数不得访问类B组员组员D.类类B不一定是类不一定是类A友元友元A私有组员私有组员封装封装D47第47页5.对于友元描述正确是(对于友元描述正确是()A友元是本类组员函数友元是本类组员函数B友元不是本类组员函数友元不是本类组员函数C友元不是函数友元不是函数D友元不能访问本类私有组员友元不能访问本类私有组员B48第48页6、给岀以下程序执行结果。、给岀以下程序执行结果。#includecl
40、asssampleintn;public:sample(inti)n=i;friendintadd(sample&s1,sample&s2);intadd(sample&s1,sample&s2)returns1.n+s2.n;voidmain()samples1(10),s2(20);coutadd(s1,s2)endl;49第49页7、先找出程序中错误,更正后分析程序执行结果:、先找出程序中错误,更正后分析程序执行结果:#includeclassB;classAinti;friendB;voiddisp()coutiendl;classBpublic:voidset(intn)Aa;a.i
41、=n;a.disp();voidmain()Bb;b.set(2);50第50页作业书本书本126页,编程题第页,编程题第1题题51第51页const变量定义时需要初始化变量定义时需要初始化。constintx=0;constint*p=&x;int*constp=&x;constint*constp=&x;5.4const5.4const对象对象const可限定变量、指针、对象、函数、函数参数、数据组可限定变量、指针、对象、函数、函数参数、数据组员、组员函数。表示不可改变。员、组员函数。表示不可改变。52第52页常量组员(常量组员(const组员组员)包含:包含:常量数据组员(常量数据组员(
42、const数据组员)数据组员)常引用常引用(const限定引用)限定引用)静态常数据组员(静态常数据组员(staticconst数据组员)数据组员)一、常量组员一、常量组员尤其注意:尤其注意:1)静态常数据组员仍保留静态组员特征,需要在)静态常数据组员仍保留静态组员特征,需要在类外初始化类外初始化。2)常量数据组员和常引用组员必须在)常量数据组员和常引用组员必须在结构函数初始化列表中结构函数初始化列表中进行初始化进行初始化。53第53页#include(lt5_7.cpp)usingnamespacestd;classBaseintx;constinta;/常数据组员常数据组员staticco
43、nstintb;/静态常数据组员静态常数据组员constint&r;/常引用常引用public:Base(int,int);voidshow()coutx,a,bendl;voiddisplay(constdouble&r)coutrendl;constintBase:b=125;Base:Base(inti,intj):x(i),a(j)voidmain()Basea1(104,118),a2(119,140);a1.show();a2.show();a1.display(3.14159);先找出程序中错误并先找出程序中错误并更正,然后分析程序更正,然后分析程序结果。结果。常数据组员常数据组
44、员必须经过初必须经过初始化列表来始化列表来取得初值取得初值,r(x)常数据组员和常常数据组员和常引用都必须经过引用都必须经过初始化列表来取初始化列表来取得初值得初值,rendl;54第54页#includeusingnamespacestd;classBaseintx;constinta;staticconstintb;constint&r;public:Base(int,int);voidshow()coutx,a,b,rendl;voiddisplay(constdouble&ref)coutrefendl;constintBase:b=125;Base:Base(inti,intj):x
45、(i),a(j),r(x)voidmain()Basea1(104,118),a2(119,140);doublex=3.14159;a1.show();a2.show();a1.display(x);常引用做函数参数,只是把常引用做函数参数,只是把实参值提供给函数使用,不实参值提供给函数使用,不允许函数改变对象值。允许函数改变对象值。55第55页引用作形参特点:引用作形参特点:形参改变会使得实参改变,形参改变会使得实参改变,引用作形参,形参不分配内存引用作形参,形参不分配内存有时需要使用引用作形参但要求形参不能改变有时需要使用引用作形参但要求形参不能改变此时可使用此时可使用const限定限定
46、二、二、constconst引用作参数引用作参数56第56页对象申明前加上对象申明前加上const限定,普通定义格式为:限定,普通定义格式为:类名类名const对象名;对象名;或者或者const类型类型对象名对象名三、常对象常对象(const对象对象)比如比如:baseconsta(25,68););constbaseb(21,32););注意:注意:1)在定义常对象时)在定义常对象时必须进行初始化必须进行初始化。2)常对象)常对象数据组员不能被更新数据组员不能被更新。57第57页分析以下程序结果分析以下程序结果(lt5_7a.cpp)#includeusingnamespacestd;cla
47、ssbaseintx,y;public:base():x(0),y(0)base(inta,intb):x(a),y(b)voidshow()coutx,yendl;cout+x,+yendl;voidmain()basea;a.show();baseb(10,20);b.show();58第58页#includeusingnamespacestd;classbaseintx,y;public:base():x(0),y(0)base(inta,intb):x(a),y(b)voidset(inta,intb)x=a;y=b;voidshow()coutx,yendl;voidmain()ba
48、sea;a.show();constbaseb(10,20);编译错误:编译错误:不能改变常对象数据组员值不能改变常对象数据组员值找出程序找出程序中错误,中错误,并说明原并说明原因因a.set(1,2);b.set(1,2);b.show();思索:怎样显示思索:怎样显示b数据组员?数据组员?编译错误:常对象只能调用编译错误:常对象只能调用常组员常组员函数函数。59第59页四、常组员函数四、常组员函数使用使用const关键词申明函数为常组员函数,申明格式以下:关键词申明函数为常组员函数,申明格式以下:类型类型函数名(参数表)函数名(参数表)const;注:注:1)const是函数说明一个组成部
49、分,所以在是函数说明一个组成部分,所以在定义部分定义部分也要也要带带const关键词。关键词。2)常组员函数不能更新对象数据组员,也不能调用该类中)常组员函数不能更新对象数据组员,也不能调用该类中没有用没有用const修饰组员函数。修饰组员函数。3)一个)一个const对象能够调用对象能够调用const函数,但不能调用非函数,但不能调用非const组员函数。组员函数。4)const限定函数与未加限定函数与未加const限定同名函数可重载。限定同名函数可重载。5)const不可限定析构函数和结构函数。不可限定析构函数和结构函数。60第60页#include/lt5_7c.cppusingname
50、spacestd;classbaseintx,y;public:base():x(0),y(0)base(inta,intb):x(a),y(b)voidset(inta,intb)x=a;y=b;voidshow()coutx,yendl;cout+x,+yendl;voidmain()basea;a.show();constbaseb(10,20);/常对象常对象b.show();const常组员常组员函数函数编译错误:常对象只能调用编译错误:常对象只能调用常组员常组员函数函数!错误:在常组员函数中,错误:在常组员函数中,不能更新对象数据组员不能更新对象数据组员61第61页#include
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100