版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
會(huì)計(jì)學(xué)1C程序設(shè)計(jì)實(shí)踐教程下11.1面向?qū)ο蟮乃枷胧裁词敲嫦蜻^(guò)程?什么是面向?qū)ο???jī)煞N不同的思想、方法。面向過(guò)程的程序設(shè)計(jì)用傳統(tǒng)程序設(shè)計(jì)語(yǔ)言進(jìn)行程序設(shè)計(jì)時(shí),必須詳細(xì)地描述解題的過(guò)程。程序設(shè)計(jì)工作主要圍繞設(shè)計(jì)解題過(guò)程來(lái)進(jìn)行,這種傳統(tǒng)的程序設(shè)計(jì)方法稱(chēng)為面向過(guò)程的程序設(shè)計(jì)。第1頁(yè)/共257頁(yè)面向過(guò)程程序設(shè)計(jì)特點(diǎn)程序——處理數(shù)據(jù)的一系列過(guò)程;數(shù)據(jù)與過(guò)程分離;程序=數(shù)據(jù)結(jié)構(gòu)+算法
缺點(diǎn)重用性差維護(hù)困難
第2頁(yè)/共257頁(yè)面向?qū)ο蟪绦蛟O(shè)計(jì)面向?qū)ο蟪绦蛟O(shè)計(jì):將面向?qū)ο蠓椒ㄓ糜诔绦蛟O(shè)計(jì)。出發(fā)點(diǎn)與基本原則:模擬人類(lèi)習(xí)慣思維方式,使開(kāi)發(fā)軟件的方法盡可能接近人類(lèi)認(rèn)識(shí)世界解決問(wèn)題的方法。對(duì)象作為模塊,對(duì)象是對(duì)客觀事物的自然的、直接的抽象和模擬,包含了數(shù)據(jù)及對(duì)數(shù)據(jù)的操作。第3頁(yè)/共257頁(yè)11.2面向?qū)ο蟪绦蛟O(shè)計(jì)的基本特點(diǎn)封裝性將描述對(duì)象的數(shù)據(jù)及處理這些數(shù)據(jù)的代碼集中起來(lái)放在對(duì)象內(nèi)部,對(duì)象成為獨(dú)立模塊。繼承性從已有類(lèi)(稱(chēng)為基類(lèi))派生出新類(lèi)。多態(tài)性同一個(gè)名字代表不同、但相似的功能。第4頁(yè)/共257頁(yè)11.3面向?qū)ο筌浖_(kāi)發(fā)的基本過(guò)程軟件危機(jī)促進(jìn)了軟件工程的形成與發(fā)展。軟件工程:用系統(tǒng)工程學(xué)的原理和方法管理軟件開(kāi)發(fā)過(guò)程,開(kāi)發(fā)過(guò)程分為分析、設(shè)計(jì)、編程、測(cè)試、維護(hù)等階段。面向?qū)ο蟮能浖こ谭治觯好鞔_系統(tǒng)必須做什么。設(shè)計(jì):明確軟件系統(tǒng)怎么做。實(shí)現(xiàn):選用合適的面向?qū)ο缶幊陶Z(yǔ)言,實(shí)現(xiàn)設(shè)計(jì)階段描述的軟件系統(tǒng)的各個(gè)類(lèi)模塊,并根據(jù)類(lèi)的相互關(guān)系集成。測(cè)試:發(fā)現(xiàn)軟件中的錯(cuò)誤。維護(hù):在軟件交付用戶(hù)使用期間,對(duì)軟件所作的修改。第5頁(yè)/共257頁(yè)11.4類(lèi)和對(duì)象在面向?qū)ο蟪绦蛟O(shè)計(jì)中,對(duì)象是構(gòu)成程序的模塊,即程序是由一組對(duì)象構(gòu)成的,對(duì)象之間通過(guò)消息分工協(xié)作,共同完成程序的功能。類(lèi)是面向?qū)ο蟪绦蛟O(shè)計(jì)的核心,是對(duì)具有相同屬性與行為的一組事物的抽象描述。利用類(lèi)可以把數(shù)據(jù)和對(duì)數(shù)據(jù)所做的操作組合成一個(gè)整體,實(shí)現(xiàn)對(duì)數(shù)據(jù)的封裝和隱藏。類(lèi)是用戶(hù)自定義的數(shù)據(jù)類(lèi)型,是創(chuàng)建對(duì)象的模型。第6頁(yè)/共257頁(yè)11.4.1類(lèi)的定義
1.格式關(guān)鍵字class類(lèi)名{
成員1說(shuō)明;成員2說(shuō)明;
……
成員n說(shuō)明;};類(lèi)定義體分號(hào)不可缺!第7頁(yè)/共257頁(yè)
2.類(lèi)的組成成員
⑴數(shù)據(jù)成員:變量或?qū)ο?。其?lèi)型為:基本類(lèi)型:int、float、double、char、bool復(fù)合類(lèi)型:數(shù)組、指針、引用、結(jié)構(gòu)、枚舉等⑵成員函數(shù)對(duì)數(shù)據(jù)成員進(jìn)行操作。第8頁(yè)/共257頁(yè)例:classCircle{private:intradius;public:voidsetRadius(intr){radius=r;}doublearea(){return3.14*radius*radius;}};數(shù)據(jù)成員函數(shù)成員1?函數(shù)成員2第9頁(yè)/共257頁(yè)在定義一個(gè)類(lèi)時(shí),注意:類(lèi)只是一種自定義數(shù)據(jù)類(lèi)型,類(lèi)中任何成員數(shù)據(jù)均不能使用關(guān)鍵字extern、auto或register指定其存儲(chǔ)類(lèi)型,也不能初始化。例如:
classCircle{intradius=5;//錯(cuò)誤
externfloatpi;//錯(cuò)誤
……//省略其它成員
};成員函數(shù)可直接使用類(lèi)中的任一成員。類(lèi)類(lèi)型與結(jié)構(gòu)體類(lèi)型相似,結(jié)構(gòu)體類(lèi)型也可有函數(shù)成員,差別在于,類(lèi)類(lèi)型的缺省訪問(wèn)權(quán)限是private,結(jié)構(gòu)體類(lèi)型的缺省訪問(wèn)權(quán)限是public。第10頁(yè)/共257頁(yè)11.4.2類(lèi)成員的訪問(wèn)控制
訪問(wèn)權(quán)限控制訪問(wèn)權(quán)限private只允許同類(lèi)的成員函數(shù)訪問(wèn)protected允許同類(lèi)及其派生類(lèi)的成員函數(shù)訪問(wèn)public允許同一作用域的任何函數(shù)訪問(wèn)在定義類(lèi)時(shí),指定其成員訪問(wèn)權(quán)限的原則:僅供該類(lèi)的成員函數(shù)訪問(wèn)的成員應(yīng)指定為私有的。若定義的成員在派生類(lèi)中也需經(jīng)常使用,則應(yīng)指定其為保護(hù)的。若允許在類(lèi)外使用成員時(shí),應(yīng)將其訪問(wèn)權(quán)限定義為公有的。第11頁(yè)/共257頁(yè)11.4.3類(lèi)的成員函數(shù)及重載成員函數(shù)必須在類(lèi)體內(nèi)給出原型說(shuō)明,至于它的實(shí)現(xiàn),可以放在類(lèi)體內(nèi),也可以放在類(lèi)體外。
當(dāng)成員函數(shù)所含代碼較少時(shí),一般直接在類(lèi)中定義該成員函數(shù);當(dāng)成員函數(shù)中所含代碼較多時(shí),通常只在類(lèi)中進(jìn)行原型的說(shuō)明,在類(lèi)外對(duì)函數(shù)進(jìn)行定義。第12頁(yè)/共257頁(yè)例:classPerson{charname[12];intage;charsex[4];public:voidPrint(){cout<<name<<','<<age<<','<<sex<<endl;}
……//省略其它成員};在類(lèi)中定義的成員函數(shù)第13頁(yè)/共257頁(yè)在類(lèi)外定義成員函數(shù)時(shí),函數(shù)名應(yīng)該包含:
類(lèi)名+作用域分辯符(::)+原函數(shù)名指明該函數(shù)是哪個(gè)類(lèi)的成員第14頁(yè)/共257頁(yè)classPerson{charname[12];intage;charsex[4];public:voidPrint();
……//省略其它成員};voidPerson::Print(){cout<<name<<','<<age<<','<<sex<<endl;}例:在類(lèi)中聲明成員函數(shù)的原型在類(lèi)外定義成員函數(shù)第15頁(yè)/共257頁(yè)類(lèi)的成員函數(shù)可以重載
例:classPerson{charname[12];intage;charsex[4];public:
void
SetPerson(constchar*,int,constchar*="女");
void
SetPerson(int);
……//省略其它成員};成員函數(shù)重載缺省參數(shù)第16頁(yè)/共257頁(yè)11.4.4對(duì)象對(duì)象的本質(zhì)一個(gè)對(duì)象就是一個(gè)類(lèi)的實(shí)例。一個(gè)對(duì)象就是一個(gè)具有某種類(lèi)類(lèi)型的變量。對(duì)象的定義格式:類(lèi)名對(duì)象名;例:
Personp1,p2;第17頁(yè)/共257頁(yè)公共代碼區(qū)SetPerson()GetName()GetSex()Print()p2.agep2.sexp1p2第18頁(yè)/共257頁(yè)訪問(wèn)對(duì)象的成員
對(duì)象名.數(shù)據(jù)成員名對(duì)象名.成員函數(shù)名(參數(shù)表)對(duì)象指針名->數(shù)據(jù)成員名對(duì)象指針名->成員函數(shù)名(參數(shù)表)
第19頁(yè)/共257頁(yè)訪問(wèn)對(duì)象的成員時(shí),要注意成員的訪問(wèn)權(quán)限。例:
#include<iostream.h>classRectangle{
floatlength,width;
public:
floatArea(){returnlength*width;}floatPerimeter(){return2*(length+width);}};private:以關(guān)鍵字class定義的類(lèi),成員的缺省訪問(wèn)屬性為private。第20頁(yè)/共257頁(yè)voidmain(){Rectangler;
r.width=45;
r.length=54.2;cout<<"theareaofrectangleis"<<r.Area()<<endl;cout<<"theperimeterofrectangleis"<<r.Perimeter()<<endl;}非法訪問(wèn)私有成員!第21頁(yè)/共257頁(yè)#include<iostream.h>classRectangle{floatlength,width;public:voidSetWidth(floatnewWidth){width=newWidth;}voidSetLength(floatnewLength){length=newLength;}floatArea(){returnlength*width;}floatPerimeter(){return2*(length+width);}};例:第22頁(yè)/共257頁(yè)voidmain(){Rectangler;//定義對(duì)象
r.SetWidth(45);r.SetLength(54.2);cout<<"Theareaofrectangleis"<<r.Area()<<endl;cout<<"Theperimeterofrectangleis"<<r.Perimeter()<<endl;}第23頁(yè)/共257頁(yè)11.4.5對(duì)象數(shù)組若一個(gè)數(shù)組中每個(gè)元素都是同類(lèi)型的對(duì)象,則稱(chēng)該數(shù)組為對(duì)象數(shù)組。定義一維對(duì)象數(shù)組的格式為:
<類(lèi)名><數(shù)組名>[<整型常量表達(dá)式>];第24頁(yè)/共257頁(yè)例11.5
對(duì)象數(shù)組的使用。#include<iostream.h>classCircle{intradius;public:voidsetRadius(intr){radius=r;}intgetRadius(){returnradius;}doublearea(){return3.14*radius*radius;}};voidmain(){Circlec[3];c[0].setRadius(6);c[1].setRadius(2);c[2].setRadius(15);for(inti=0;i<3;i++)cout<<"radius:"<<c[i].getRadius()<<",area:"<<c[i].area()<<endl;}類(lèi)Circle的定義定義對(duì)象數(shù)組第25頁(yè)/共257頁(yè)11.4.6this指針一個(gè)成員函數(shù)被調(diào)用時(shí),系統(tǒng)自動(dòng)向它傳遞一個(gè)隱含的指針,該指針是調(diào)用該成員函數(shù)的對(duì)象的指針,在成員函數(shù)的函數(shù)體中可直接用this使用該指針。在成員函數(shù)的實(shí)現(xiàn)中,當(dāng)訪問(wèn)該對(duì)象的某成員時(shí),系統(tǒng)自動(dòng)使用這個(gè)隱含的this指針。在定義成員函數(shù)的函數(shù)體時(shí),通常省略this指針。例:Circle類(lèi)的成員函數(shù)
voidsetRadius(intr){
radius=r;}this->this指針具有如下的缺省說(shuō)明:
Circle*constthis;
第26頁(yè)/共257頁(yè)有時(shí)不得不顯式使用this指針。數(shù)據(jù)成員名與函數(shù)成員的形參同名。例:className{char*name;public:voidSetName(char*name){if(name){this->name=newchar[strlen(name)+1];strcpy(this->name,name);}elsethis->name=NULL;}……};第27頁(yè)/共257頁(yè)引用對(duì)象本身。例:className{char*name;public:voidCopyName(Name&n){if(this==&n)return;//避免對(duì)象自我復(fù)制
deletename;if(){name=newchar[strlen()+1];strcpy(name,);}elsename=NULL;}
……
};第28頁(yè)/共257頁(yè)11.5構(gòu)造函數(shù)和析構(gòu)函數(shù)構(gòu)造函數(shù)和析構(gòu)函數(shù):類(lèi)的特殊成員。構(gòu)造函數(shù):創(chuàng)建對(duì)象,并初始化對(duì)象的數(shù)據(jù)成員。析構(gòu)函數(shù):撤銷(xiāo)對(duì)象,收回它所占內(nèi)存,及完成其它清理工作。第29頁(yè)/共257頁(yè)11.5.1構(gòu)造函數(shù)構(gòu)造函數(shù)的定義格式
ClassName(<形參表>){…}//函數(shù)體①它與所在類(lèi)同名。②它不得有返回值,甚至連關(guān)鍵字void也不許有。第30頁(yè)/共257頁(yè)
例:classPerson{charname[12];intage;charsex[4];public:
Person(constchar*n,inta,constchar*s){strcpy(name,n);age=a;strcpy(sex,s);}
……
//省略其它成員函數(shù)};第31頁(yè)/共257頁(yè)
例:classPerson{charname[12];intage;charsex[4];public:
Person(constchar*n,inta,constchar*s);
…
//其它成員函數(shù)說(shuō)明};Person::Person(constchar*n,inta,constchar*s){strcpy(name,n);age=a;strcpy(sex,s);}也可在類(lèi)中聲明原型,在類(lèi)外定義。第32頁(yè)/共257頁(yè)
構(gòu)造函數(shù)的特殊性:①構(gòu)造函數(shù)在定義類(lèi)對(duì)象時(shí)由系統(tǒng)自動(dòng)調(diào)用。例:voidmain(){Personp(“張三”,20,“男”
);
……}當(dāng)遇此定義語(yǔ)句時(shí),系統(tǒng)就調(diào)用構(gòu)造函數(shù):
Person(constchar*n,inta,constchar*s)創(chuàng)建對(duì)象p,并用實(shí)參初始化它的數(shù)據(jù)成員。第33頁(yè)/共257頁(yè)②構(gòu)造函數(shù)可以重載。例:classPoint{floatx,y;public:Point(){x=0;y=0};//(1)Point(floata,floatb){x=a;y=b;}//(2)
//…};voidmain(){Pointp1;//匹配(1)Pointp2(2.0,4.2);//匹配(2)}第34頁(yè)/共257頁(yè)構(gòu)造函數(shù)中初始化數(shù)據(jù)成員的方法在函數(shù)體中用賦值等語(yǔ)句進(jìn)行使用成員初始化列表
第35頁(yè)/共257頁(yè)初始化列表①格式:在形參表和函數(shù)體之間,以:號(hào)開(kāi)頭,由多個(gè)以逗號(hào)分隔的初始化項(xiàng)構(gòu)成。即
:數(shù)據(jù)成員名1(初值1),…,數(shù)據(jù)成員名n(初值n)②舉例:
Person::Person():name("zhang"),age(22){strcpy(sex,"男");}③執(zhí)行順序:帶有初始化表的構(gòu)造函數(shù)執(zhí)行時(shí),首先執(zhí)行初始化表,然后再執(zhí)行函數(shù)體。第36頁(yè)/共257頁(yè)數(shù)據(jù)成員的初始化普通數(shù)據(jù)成員的初始化既可在函數(shù)體進(jìn)行,也可在初始化表進(jìn)行。例:(方法1)Point::Point(intx1,inty1){x=x1;y=y1;}或(方法2)Point::Point(intx1,inty1):x(x1),y(y1){}const數(shù)據(jù)成員、const對(duì)象成員和從基類(lèi)繼承的數(shù)據(jù)成員的初始化必須用初始化表。第37頁(yè)/共257頁(yè)缺省的構(gòu)造函數(shù)①C++規(guī)定,每個(gè)類(lèi)至少有一個(gè)構(gòu)造函數(shù),否則就不能創(chuàng)建該類(lèi)的對(duì)象。例:classRectangle{floatlength,width;public:floatArea();floatPerimeter();};
……
//類(lèi)的實(shí)現(xiàn)voidmain(){
Rectanglerect;
……}能否創(chuàng)建Rectangle類(lèi)的對(duì)象?第38頁(yè)/共257頁(yè)②類(lèi)中若未定義構(gòu)造函數(shù),則C++編譯系統(tǒng)自動(dòng)提供一個(gè)缺省的構(gòu)造函數(shù)。缺省的構(gòu)造函數(shù)無(wú)參,函數(shù)體為空,僅創(chuàng)建對(duì)象,不作任何初始化工作。classRectangle{floatlength,width;public:floatArea();floatPerimeter();};
……
//類(lèi)的實(shí)現(xiàn)voidmain(){Rectanglerect;
……}因系統(tǒng)提供了默認(rèn)的構(gòu)造函數(shù):
Rectangle(){}第39頁(yè)/共257頁(yè)③只要類(lèi)中定義了一個(gè)構(gòu)造函數(shù),C++編譯器就不再提供缺省的構(gòu)造函數(shù),如還想要無(wú)參構(gòu)造函數(shù),則必須自己定義。例:
classCircle{intradius;
public:Circle(intr){radius=r;}//(1)};Circlec1;Circlec2(5);因該類(lèi)有帶一個(gè)參數(shù)的構(gòu)造函數(shù),故系統(tǒng)不再提供無(wú)參的缺省構(gòu)造函數(shù)!匹配(1)沒(méi)有無(wú)參構(gòu)造函數(shù)第40頁(yè)/共257頁(yè)對(duì)上例的修改方法1:classCircle{intradius;public:Circle(intr){radius=r;}//(1)
Circle(){}//(2)};Circlec1(3);Circlec2;匹配(1)匹配(2)添加無(wú)參構(gòu)造函數(shù)!第41頁(yè)/共257頁(yè)對(duì)上例的修改方法2:classCircle{intradius;public:Circle(intr=0){radius=r;}//(1)};Circlec1(3);Circlec2;匹配(1)匹配(1)參數(shù)帶默認(rèn)值的構(gòu)造函數(shù)!所有參數(shù)都帶默認(rèn)值的構(gòu)造函數(shù)也是缺省的構(gòu)造函數(shù)。第42頁(yè)/共257頁(yè)
使用參數(shù)帶缺省值的構(gòu)造函數(shù)時(shí),應(yīng)防二義性。如:
classCircle{intradius;public:Circle(){}//L1Circle(intr=0){radius=r;}//L2};
Circlec1;//L3錯(cuò)誤!產(chǎn)生二義性
Circlec2(5);//匹配L2行的構(gòu)造函數(shù)當(dāng)編譯L3行的語(yǔ)句時(shí),出錯(cuò)。因Circle類(lèi)定義了兩個(gè)缺省的構(gòu)造函數(shù),編譯器不知道是調(diào)用L1行定義的Circle()還是調(diào)用L2行定義的Circle(intr=0)。第43頁(yè)/共257頁(yè)11.5.2析構(gòu)函數(shù)作用:與構(gòu)造函數(shù)相反,在對(duì)象被撤消時(shí)由系統(tǒng)自動(dòng)調(diào)用,做清理工作。特點(diǎn):析構(gòu)函數(shù)名必須與類(lèi)名相同,并在其前面加上字符“~”,以便和構(gòu)造函數(shù)名相區(qū)別。析構(gòu)函數(shù)沒(méi)有返回值,函數(shù)名前也不能用關(guān)鍵字void。析構(gòu)函數(shù)沒(méi)有參數(shù),換言之,析構(gòu)函數(shù)是唯一的,析構(gòu)函數(shù)無(wú)法重載。第44頁(yè)/共257頁(yè)例11.9調(diào)用析構(gòu)函數(shù)。
#include<iostream.h>classPoint{intx,y;public:Point(){x=y=0;cout<<"Defaultconstructorcalled.\n";}Point(inta,intb){x=a;y=b;cout<<"Constructorwithparameterscalled.\n";}~Point(){cout<<"Destructorcalled."<<x<<','<<y<<'\n';}voidprint(){cout<<x<<','<<y<<'\n';}};為了觀察調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的過(guò)程,分別在構(gòu)造函數(shù)和析構(gòu)函數(shù)內(nèi)添加了輸出調(diào)用信息的語(yǔ)句。第45頁(yè)/共257頁(yè)voidmain(){Pointp1(5,8),p2;p1.print();p2.print();{Pointp2(3,2);p2.print();}cout<<"Exitmain!\n";}程序運(yùn)行結(jié)果:Constructorwithparameterscalled.Defaultconstructorcalled.5,80,0Constructorwithparameterscalled.3,2Destructorcalled.3,2Exitmain!Destructorcalled.0,0Destructorcalled.5,8從該程序的輸出結(jié)果看:當(dāng)創(chuàng)建對(duì)象時(shí),系統(tǒng)自動(dòng)調(diào)用相匹配的構(gòu)造函數(shù);當(dāng)撤銷(xiāo)對(duì)象時(shí),系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù)。對(duì)象撤銷(xiāo)的順序與創(chuàng)建的順序正好相反。在相同的生存期的情況下,先創(chuàng)建的對(duì)象后撤銷(xiāo),后創(chuàng)建的對(duì)象先撤銷(xiāo)。第46頁(yè)/共257頁(yè)若類(lèi)的定義中沒(méi)有顯式定義析構(gòu)函數(shù),則編譯器自動(dòng)為該類(lèi)產(chǎn)生一個(gè)缺省的析構(gòu)函數(shù)。其格式為:
ClassName::~ClassName(){}
它不執(zhí)行任何操作。無(wú)需顯式定義析構(gòu)函數(shù)的典型情況:撤消對(duì)象時(shí)不做任何清理工作。需要顯式定義析構(gòu)函數(shù)的典型情況:類(lèi)中包含指向動(dòng)態(tài)內(nèi)存的指針數(shù)據(jù)成員。由于它們所指向的動(dòng)態(tài)內(nèi)存空間是對(duì)象自己管理的,因此在對(duì)象即將撤消時(shí),需通過(guò)析構(gòu)函數(shù)將所管理的動(dòng)態(tài)內(nèi)存空間及時(shí)釋放。第47頁(yè)/共257頁(yè)例11.10
使用析構(gòu)函數(shù),收回動(dòng)態(tài)分配的存儲(chǔ)空間。#include<iostream.h>#include<string.h>classPerson{
char*name;intage;public:Person(char*n,inta){if(n){name=newchar[strlen(n)+1];strcpy(name,n);}elsename=0;age=a;}~Person(){delete[]name;}voidPrint(){cout<<name<<','<<age<<endl;}};voidmain(){Personp(“John”,20);p.Print();}申請(qǐng)動(dòng)態(tài)內(nèi)存釋放動(dòng)態(tài)內(nèi)存第48頁(yè)/共257頁(yè)對(duì)象釋放順序:對(duì)象釋放的順序與創(chuàng)建的順序正好相反。在相同的生存期的情況下,先創(chuàng)建的對(duì)象后釋放,后創(chuàng)建的對(duì)象先釋放。第49頁(yè)/共257頁(yè)11.5.3構(gòu)造函數(shù)的類(lèi)型轉(zhuǎn)換功能如果類(lèi)定義中提供了只帶一個(gè)參數(shù)(沒(méi)有其它參數(shù),或其它參數(shù)都有缺省值)的構(gòu)造函數(shù),則當(dāng)一個(gè)其它類(lèi)型的數(shù)值或變量x賦值給該類(lèi)的對(duì)象A時(shí),由于類(lèi)型不一致,系統(tǒng)自動(dòng)以x為實(shí)參調(diào)用該類(lèi)的單參數(shù)構(gòu)造函數(shù),創(chuàng)建一個(gè)該類(lèi)的臨時(shí)對(duì)象,并將該臨時(shí)對(duì)象賦值給A,從而實(shí)現(xiàn)了隱式類(lèi)型轉(zhuǎn)換。第50頁(yè)/共257頁(yè)例11.11
構(gòu)造函數(shù)完成類(lèi)型轉(zhuǎn)換功能的例子。#include<iostream.h>classMoney{intyuan,jiao,fen;public:
Money(doubled)
{intt=d*100;yuan=t/100;jiao=(t-yuan*100)/10;fen=t%10;}Money(inty=0,intj=0,intf=0){yuan=y;jiao=j;fen=f;}voidprint(){cout<<yuan<<“元”<<jiao<<“角”<<fen<<“分\n";}};單參數(shù)構(gòu)造函數(shù)第51頁(yè)/共257頁(yè)voidmain(){Moneym1(25,5,7),m2(2.65);m1.print();m2.print();Moneym3=4.57;m3.print();
m3=3.29;
m3.print();}隱式類(lèi)型轉(zhuǎn)換:調(diào)用單參數(shù)構(gòu)造函數(shù),創(chuàng)建Money類(lèi)型的臨時(shí)對(duì)象。并不做隱式類(lèi)型轉(zhuǎn)換,等價(jià)于:
Moneym3(4.57);第52頁(yè)/共257頁(yè)11.5.4拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù):特殊的構(gòu)造函數(shù),其形參是本類(lèi)的對(duì)象的引用,其作用是使用一個(gè)已經(jīng)存在的對(duì)象(由拷貝構(gòu)造函數(shù)的參數(shù)指定的對(duì)象)去初始化一個(gè)新的同類(lèi)的對(duì)象。定義一個(gè)拷貝構(gòu)造函數(shù)的一般形式為:
ClassName::ClassName(ClassName&c){...}//函數(shù)體完成對(duì)應(yīng)數(shù)據(jù)成員的賦值第53頁(yè)/共257頁(yè)例11.12使用完成拷貝功能的構(gòu)造函數(shù)。#include<iostream.h>#include<math.h>classPoint{intx,y;public:Point(inta=0,intb=0){x=a;y=b;}
Point(Point&t)//拷貝構(gòu)造函數(shù)
{x=t.x;y=t.y;cout<<"調(diào)用了拷貝構(gòu)造函數(shù)!\n";}intGetX(){returnx;}intGetY(){returny;}voidShow(){cout<<"x="<<x<<",y="<<y<<'\n';}};第54頁(yè)/共257頁(yè)doubleDistance(Pointp1,Pointp2){intdx=p1.GetX()-p2.GetX();intdy=p1.GetY()-p2.GetY();returnsqrt(dx*dx+dy*dy);}PointMid(Point&p1,Point&p2){intx=(p1.GetX()+p2.GetX())/2;inty=(p1.GetY()+p2.GetY())/2;returnPoint(x,y);}voidmain(){Pointp0,p1(8,15);
Pointp2(p1);//調(diào)用拷貝構(gòu)造函數(shù)
Pointp3=p1;//等價(jià):Pointp3(p1);p1.Show();p2.Show();p3.Show();p3=Mid(p0,p3);cout<<Distance(p0,p3)<<endl;}函數(shù)Distance(Point,Point)的形參為類(lèi)的對(duì)象,當(dāng)執(zhí)行函數(shù)調(diào)用distance(p0,p3)時(shí),實(shí)參初始化形參,兩次調(diào)用拷貝構(gòu)造函數(shù),分別用實(shí)參對(duì)象p0和p3初始化形參對(duì)象p1和p2。若函數(shù)形參是對(duì)象的引用,則調(diào)用該函數(shù)時(shí),不調(diào)用拷貝構(gòu)造函數(shù),如本例的Mid函數(shù)所示。結(jié)果(VC6withsp6):調(diào)用了拷貝構(gòu)造函數(shù)!調(diào)用了拷貝構(gòu)造函數(shù)!x=8,y=15x=8,y=15x=8,y=15調(diào)用了拷貝構(gòu)造函數(shù)!調(diào)用了拷貝構(gòu)造函數(shù)!8.06226第55頁(yè)/共257頁(yè)默認(rèn)拷貝構(gòu)造函數(shù):若定義類(lèi)時(shí)未顯式定義該類(lèi)的拷貝構(gòu)造函數(shù),則編譯系統(tǒng)會(huì)在編譯該類(lèi)時(shí)自動(dòng)生成一個(gè)默認(rèn)拷貝構(gòu)造函數(shù)。默認(rèn)拷貝構(gòu)造函數(shù)的功能是把一個(gè)已經(jīng)存在的對(duì)象的每個(gè)數(shù)據(jù)成員的值逐個(gè)復(fù)制到新建立對(duì)象對(duì)應(yīng)的數(shù)據(jù)成員中。例11.12中類(lèi)Point的拷貝構(gòu)造函數(shù)與默認(rèn)的拷貝構(gòu)造函數(shù)功能一樣,不必顯式定義。何時(shí)顯式定義拷貝構(gòu)造函數(shù)?若類(lèi)中包含指向動(dòng)態(tài)內(nèi)存的指針時(shí),用默認(rèn)的拷貝構(gòu)造函數(shù)初始化對(duì)象,將帶來(lái)嚴(yán)重問(wèn)題,如例11.13所示。第56頁(yè)/共257頁(yè)例11.13默認(rèn)拷貝的構(gòu)造函數(shù)。#include<iostream.h>#include<string.h>classString{char*p;public:String(char*c=0){if(c){p=newchar[strlen(c)+1];strcpy(p,c);}elsep=NULL;}~String(){delete[]p;}voidShow(){cout<<"string="<<p<<'\n';}};voidmain(){Strings1("student");
Strings2(s1);//As1.Show();s2.Show();}第57頁(yè)/共257頁(yè)s1.ps1堆內(nèi)存s2.ps2執(zhí)行A行語(yǔ)句:調(diào)用默認(rèn)拷貝構(gòu)造函數(shù),用s1對(duì)象初始化s2對(duì)象,使s2對(duì)象的成員指針p與s1對(duì)象的成員指針p指向同一片內(nèi)存。主函數(shù)結(jié)束:先撤消s2,s2對(duì)象釋放其所指動(dòng)態(tài)內(nèi)存;其后撤銷(xiāo)s1對(duì)象,但因s1對(duì)象所指動(dòng)態(tài)內(nèi)存已被s2對(duì)象釋放,造成重復(fù)釋放同一塊動(dòng)態(tài)內(nèi)存,出現(xiàn)運(yùn)行錯(cuò)誤。定義拷貝構(gòu)造函數(shù),避免上述錯(cuò)誤:
String(String&s){if(s.p){p=newchar[strlen(s.p)+1];strcpy(p,s.p);}elsep=0;}studen\0t第58頁(yè)/共257頁(yè)11.5.5對(duì)象成員與構(gòu)造函數(shù)對(duì)象成員:一個(gè)類(lèi)的對(duì)象可做另一個(gè)類(lèi)的數(shù)據(jù)成員。例如:
classDate{intyear,month,day;public:Date(inty,intm,intd){year=y;month=m;day=d;}};classPerson{charname[12];charsex[4];
Datebirthday;//對(duì)象成員
public:Person(char*,char*,int,int,int);
…};第59頁(yè)/共257頁(yè)對(duì)象成員的初始化通過(guò)初始化表進(jìn)行,如:
Person::Person(char*n,char*s,inty,intm,intd)
:birthday(y,m,d){strcpy(name,n);strcpy(sex,s);}若未在初始化表中初始化對(duì)象成員,則系統(tǒng)自動(dòng)調(diào)用該對(duì)象成員的缺省的構(gòu)造函數(shù)來(lái)初始化。若類(lèi)中包含對(duì)象成員,則在創(chuàng)建該類(lèi)的對(duì)象時(shí),先調(diào)用對(duì)象成員的構(gòu)造函數(shù),初始化相應(yīng)的對(duì)象成員,后執(zhí)行該類(lèi)的構(gòu)造函數(shù),初始化該類(lèi)的其他成員。如果一個(gè)類(lèi)包含多個(gè)對(duì)象成員,對(duì)象成員的構(gòu)造函數(shù)的調(diào)用順序由它們?cè)谠擃?lèi)中的說(shuō)明順序決定,而與它們?cè)诔跏蓟碇械捻樞驘o(wú)關(guān)。第60頁(yè)/共257頁(yè)例11.14初始化對(duì)象成員。#include<iostream.h>classPoint{intx,y;public:Point(inta,intb){x=a;y=b;cout<<"ConstructorofclassPointiscalled.\n";}voidShow(){cout<<"x="<<x<<",y="<<y<<endl;}};第61頁(yè)/共257頁(yè)classRectangle{
Pointp;intlength,width;public:Rectangle(intl,intw,inta,intb):p(a,b){length=l;width=w;cout<<"ConstructorofclassRectangleiscalled.\n";}voidShow(){p.Show();cout<<"length="<<length<<",width="<<width<<endl;}};voidmain(){Rectangler(5,4,45,55);r.Show();}程序運(yùn)行結(jié)果:ConstructorofclassPointiscalled.ConstructorofclassRectangleiscalled.x=45,y=55length=5,width=4第62頁(yè)/共257頁(yè)11.6友元有時(shí)需要在對(duì)象外部頻繁訪問(wèn)對(duì)象私有的或保護(hù)的數(shù)據(jù)成員,若通過(guò)調(diào)用公有成員函數(shù)間接訪問(wèn),由于參數(shù)傳遞、類(lèi)型檢查等都需占用時(shí)間,必然降低程序的運(yùn)行效率。使用友元可在對(duì)象外部直接訪問(wèn)對(duì)象私有的和保護(hù)的數(shù)據(jù)成員。友元以類(lèi)的封裝性的有限破壞為代價(jià)來(lái)提高程序的運(yùn)行效率,應(yīng)謹(jǐn)慎使用。友元分為:友元函數(shù)和友元類(lèi)。第63頁(yè)/共257頁(yè)11.6.1友元函數(shù)友元函數(shù)的說(shuō)明格式:
friend<type>FuncName(<args>);例11.15用友元函數(shù)的方法計(jì)算兩點(diǎn)距離。
#include<iostream.h>#include<math.h>classPoint{intx,y;public:Point(inti=0,intj=0){x=i;y=j;}intGetX(){returnx;}intGetY(){returny;}
frienddoubledistance(Point&,Point&);};普通函數(shù)distance()聲明為Point類(lèi)的友元函數(shù)。第64頁(yè)/共257頁(yè)doubledistance(Point&p1,Point&p2){intdx=p1.x-p2.x,dy=p1.y-p2.y;returnsqrt(dx*dx+dy*dy);}voidmain(){Pointa(8,15),b(3,7);cout<<"Thedistanceis:"<<distance(a,b)<<endl;}程序運(yùn)行結(jié)果:Thedistanceis:9.43398友元函數(shù)distance()可通過(guò)對(duì)象名直接訪問(wèn)Point類(lèi)的對(duì)象p1和p2的私有數(shù)據(jù)成員x和y,提高了程序的效率。第65頁(yè)/共257頁(yè)友元函數(shù)說(shuō)明:友元函數(shù)應(yīng)在類(lèi)中說(shuō)明,可放在類(lèi)的私有、公有或保護(hù)部分,效果一樣。友元函數(shù)體可在類(lèi)內(nèi)或類(lèi)外定義。友元函數(shù)不是類(lèi)的成員,不帶this指針,因此必須將對(duì)象名或?qū)ο蟮囊米鳛橛言瘮?shù)的參數(shù),并在函數(shù)體中用運(yùn)算符“.”來(lái)訪問(wèn)對(duì)象的成員。如上例中的p1.x。友元函數(shù)可直接訪問(wèn)相關(guān)類(lèi)中的所有成員。一個(gè)類(lèi)的成員函數(shù)也可作為另一個(gè)類(lèi)的友元函數(shù),例如:
classA{
…intf(…);};classB{
…//成員定義
friendintA::f(…);//聲明類(lèi)A的成員函數(shù)f()};//是類(lèi)B的友元在聲明這個(gè)友元函數(shù)時(shí)需要在函數(shù)名前面加上它的類(lèi)名和作用域運(yùn)算符“::”。第66頁(yè)/共257頁(yè)11.6.2友元類(lèi)若聲明A類(lèi)為B類(lèi)的友元,則A類(lèi)的所有成員函數(shù)都成為B類(lèi)的友元函數(shù)。有時(shí)友元類(lèi)的使用也是必要的選擇。例11.16友元類(lèi)。#include<iostream.h>#include<string.h>classDate{intyear,month,day;public:Date(inty=0,intm=0,intd=0){year=y;month=m;day=d;}voiddisplay(){cout<<year<<month<<day;}friendclassPerson;};第67頁(yè)/共257頁(yè)classPerson{charname[12];charsex[4];Datebirthday;public:Person(char*n,inty,intm,intd,char*s){strcpy(name,n);strcpy(sex,s);
birthday.year=y;birthday.month=m;birthday.day=d;}voiddisplay(){cout<<"name:"<<name<<",sex:"<<sex;cout<<",birthday:"<<birthday.year<<'.‘<<birthday.month<<'.'<<birthday.day<<endl;}};voidmain(){Personp(“張三”,1983,8,20,”男”);p.display();}程序運(yùn)行結(jié)果:name:張三,sex:男,birthday:1983.8.20因Person類(lèi)為Date類(lèi)的友元,在Person類(lèi)的成員函數(shù)可直接操作Date類(lèi)的對(duì)象birthday的數(shù)據(jù)成員。第68頁(yè)/共257頁(yè)友元的其它注意事項(xiàng):友元關(guān)系沒(méi)有傳遞性。例如,說(shuō)明類(lèi)A是類(lèi)B的友元,類(lèi)B是類(lèi)C的友元時(shí),類(lèi)A并不一定是類(lèi)C的友元。友元關(guān)系不具有交換性,即說(shuō)明類(lèi)A為類(lèi)B的友元時(shí),類(lèi)B并不一定是類(lèi)A的友元。友元關(guān)系沒(méi)有繼承性。因友元函數(shù)不是類(lèi)的成員函數(shù),當(dāng)然不存在繼承關(guān)系。謹(jǐn)慎使用友元。友元提高程序的運(yùn)行效率是通過(guò)破壞類(lèi)的封裝性取得的,若過(guò)多過(guò)濫使用友元,則會(huì)嚴(yán)重降低程序的可維護(hù)性。第69頁(yè)/共257頁(yè)11.7類(lèi)的靜態(tài)成員
分類(lèi):靜態(tài)數(shù)據(jù)成員靜態(tài)成員函數(shù)第70頁(yè)/共257頁(yè)11.7.1靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員的必要性//學(xué)生類(lèi)classStudent{intNo;char*name;
…}若要統(tǒng)計(jì)學(xué)生總數(shù),這個(gè)數(shù)據(jù)存放在什么地方呢?
類(lèi)外變量?不能實(shí)現(xiàn)數(shù)據(jù)的隱藏!
類(lèi)中增加數(shù)據(jù)成員?冗余!不一致!第71頁(yè)/共257頁(yè)靜態(tài)數(shù)據(jù)成員的定義:先在類(lèi)體內(nèi),做引用性說(shuō)明,即在該成員名的類(lèi)型說(shuō)明符前加關(guān)鍵字static。后在文件作用域做定義性說(shuō)明。例:
classStudent{intNo;char*name;
static
intcount;//引用性說(shuō)明:說(shuō)明靜態(tài)
//數(shù)據(jù)成員count的訪問(wèn)權(quán)限和作用域
…};
intStudent::count=0;//定義性說(shuō)明:為靜態(tài)
//數(shù)據(jù)成員count分配內(nèi)存和初始化第72頁(yè)/共257頁(yè)與普通數(shù)據(jù)成員的區(qū)別:類(lèi)的普通數(shù)據(jù)成員在類(lèi)的每個(gè)對(duì)象中都擁有一個(gè)拷貝;而靜態(tài)數(shù)據(jù)成員,每個(gè)類(lèi)只有一個(gè)拷貝,由該類(lèi)的所有對(duì)象共同維護(hù)和使用,從而實(shí)現(xiàn)了同一類(lèi)的不同對(duì)象之間的數(shù)據(jù)共享。例:voidmain(){
Students1,s2;}s1.Ns1s2.Ns2count靜態(tài)存儲(chǔ)區(qū)s1與s2共有第73頁(yè)/共257頁(yè)
靜態(tài)數(shù)據(jù)成員的引用:類(lèi)名::靜態(tài)數(shù)據(jù)成員名或?qū)ο竺?靜態(tài)數(shù)據(jù)成員名或?qū)ο笾羔?>靜態(tài)數(shù)據(jù)成員名訪問(wèn)靜態(tài)數(shù)據(jù)成員時(shí)也要注意訪問(wèn)權(quán)限。第74頁(yè)/共257頁(yè)例11.17
具有靜態(tài)數(shù)據(jù)成員的Apple類(lèi)。
#include<iostream.h>classApple{floatweight;
staticintcount;//靜態(tài)數(shù)據(jù)成員的引用性說(shuō)明
staticfloattotal_weight;public:Apple(float=0);~Apple();voidShow();};
第75頁(yè)/共257頁(yè)Apple::Apple(floatw){weight=w;count++;
total_weight+=weight;cout<<"Numberofapples="<<count<<'\n';}Apple::~Apple(){count--;total_weight-=weight;cout<<"Numberofapples="<<count<<'\n';}voidApple::Show(){cout<<"weight="<<weight<<",total_weight="<<total_weight<<'\n';}第76頁(yè)/共257頁(yè)//靜態(tài)數(shù)據(jù)成員的定義性說(shuō)明:默認(rèn)值為0intApple::count;floatApple::total_weight;voidmain(){Appleredone(100);Applegreenone(200);Appleyellowone(250);redone.Show();greenone.Show();yellowone.Show();}第77頁(yè)/共257頁(yè)11.7.2靜態(tài)成員函數(shù)采用靜態(tài)函數(shù)成員的好處是可以不依賴(lài)于任何對(duì)象,直接訪問(wèn)靜態(tài)數(shù)據(jù)成員。靜態(tài)成員函數(shù)的定義格式:
static
返回值類(lèi)型成員函數(shù)名(參數(shù)表);靜態(tài)成員函數(shù)的引用格式:
<類(lèi)名>::<靜態(tài)成員函數(shù)>(<參數(shù)表>)
或
<對(duì)象名>.<靜態(tài)成員函數(shù)>(<參數(shù)表>)第78頁(yè)/共257頁(yè)例11.18具有靜態(tài)數(shù)據(jù)成員和靜態(tài)成員函數(shù)的Apple類(lèi)。
#include<iostream.h>classApple{floatweight;
staticintcount;
staticfloattotal_weight;public:Apple(float=0);~Apple();voidShowWeight();
staticvoidShowCount();
staticvoidShowTotalWeight();};
第79頁(yè)/共257頁(yè)Apple::Apple(floatw){weight=w;count++;total_weight+=weight;cout<<"Numberofapples="<<count<<'\n';}Apple::~Apple(){count--;total_weight-=weight;cout<<"Numberofapples="<<count<<'\n';}voidApple::ShowWeight(){cout<<"weight="<<weight<<'\n';}voidApple::ShowCount(){cout<<"Numberofapples="<<count<<'\n';}voidApple::ShowTotalWeight(){cout<<"Totalweightofapples="<<total_weight<<'\n';}第80頁(yè)/共257頁(yè)intApple::count;floatApple::total_weight;voidmain(){Apple::ShowCount();
Apple::ShowTotalWeight();Appleredone(100),greenone(200),yellowone(250);
redone.ShowWeight();greenone.ShowWeight();yellowone.ShowWeight();
Apple::ShowCount();
Apple::ShowTotalWeight();}程序運(yùn)行結(jié)果:Numberofapples=0Totalweightofapples=0weight=100weight=200weight=250Numberofapples=3Totalweightofapples=550第81頁(yè)/共257頁(yè)靜態(tài)成員函數(shù)可直接訪問(wèn)靜態(tài)數(shù)據(jù)成員,但不能直接訪問(wèn)非靜態(tài)數(shù)據(jù)成員(因其沒(méi)有this指針)。若要訪問(wèn)非靜態(tài)數(shù)據(jù)成員,則可通過(guò)形參對(duì)象來(lái)訪問(wèn)。如:
classMyclass{intx;staticinty;public:staticintf(Myclassm);};intMyclass::y=9;intMyclass::f(Myclassm){cout<<x+y;//對(duì)x的訪問(wèn)是錯(cuò)誤的
returnm.x+y;//正確
}第82頁(yè)/共257頁(yè)11.8const對(duì)象和成員函數(shù)常成員函數(shù):在參數(shù)表后用const修飾。定義格式:
<類(lèi)型說(shuō)明符><函數(shù)名>(<參數(shù)表>)const;特點(diǎn):常成員函數(shù)不能直接改變本對(duì)象的數(shù)據(jù)成員,也不能調(diào)用該對(duì)象的非const成員函數(shù)間接改變本對(duì)象的數(shù)據(jù)成員,否則編譯時(shí)會(huì)產(chǎn)生出錯(cuò)信息。用途:主要用于定義不改變數(shù)據(jù)成員的成員函數(shù)。const對(duì)象:用const說(shuō)明的對(duì)象。定義格式:
const<類(lèi)名><對(duì)象名>(<初值>);特點(diǎn):其數(shù)據(jù)成員在該對(duì)象的生存期間不能改變。例如:
constDatebirthday(1983,7,13);const對(duì)象只能調(diào)用常成員函數(shù)(構(gòu)造函數(shù)和析構(gòu)函數(shù)除外),以保證其數(shù)據(jù)成員不被修改。第83頁(yè)/共257頁(yè)例11.19
常成員函數(shù)舉例。
#include<iostream.h>classDate{intyear,month,day;public:Date(inty,intm,intd){year=y;month=m;day=d;}voidSetDate(inty,intm,intd){year=y;month=m;day=d;}voiddisplay(){cout<<year<<','<<month<<','<<day<<endl;}voiddisplay()
const{cout<<year<<','<<month<<','<<day<<endl;}};第84頁(yè)/共257頁(yè)voidmain(){Dateweekend(2005,7,8);weekend.display();weekend.SetDate(2005,7,22);weekend.display();
constDatebirthday(1983,7,13);
birthday.display();}程序運(yùn)行結(jié)果:2005,7,82005,7,221983,7,13第85頁(yè)/共257頁(yè)常對(duì)象和常成員函數(shù)的說(shuō)明:常成員函數(shù)在類(lèi)外定義時(shí)也應(yīng)帶const關(guān)鍵字。例如:
voidDate::display()const{cout<<year<<','<<month<<','<<day<<endl;}常成員函數(shù)不能直接改變本對(duì)象的數(shù)據(jù)成員,也不能調(diào)用該對(duì)象的非const成員函數(shù)間接改變本對(duì)象的數(shù)據(jù)成員。若常成員函數(shù)改變數(shù)據(jù)成員的值,則編譯時(shí)將出現(xiàn)出錯(cuò)信息。const可用于區(qū)分函數(shù)的重載。如類(lèi)Date中有聲明:
voiddisplay();voiddisplay()const;常對(duì)象只能調(diào)用其常成員函數(shù),不能調(diào)用其它成員函數(shù)。若常對(duì)象調(diào)用非const成員函數(shù),如:
birthday.SetDate(2005,7,22);
則編譯時(shí)將出現(xiàn)出錯(cuò)信息。第86頁(yè)/共257頁(yè)11.9應(yīng)用實(shí)例例11.20用類(lèi)和對(duì)象編程解決實(shí)際問(wèn)題。設(shè)有若干學(xué)生數(shù)據(jù),包括學(xué)號(hào)、姓名、數(shù)學(xué)成績(jī)和C++成績(jī),求每位學(xué)生的總分及每門(mén)課程的平均分。分析:Student類(lèi)包括學(xué)號(hào)、姓名等數(shù)據(jù)成員,以及對(duì)這些數(shù)據(jù)進(jìn)行操作的函數(shù)成員。其中,靜態(tài)數(shù)據(jù)成員count、msum和csum,分別存放學(xué)生人數(shù)、數(shù)學(xué)和C++課程的總分。鏈表類(lèi)StuList用于存放學(xué)生數(shù)據(jù),可完成鏈表創(chuàng)建、輸出等任務(wù)。它聲明為類(lèi)Student的友元,更便于高效操作Student類(lèi)的數(shù)據(jù)成員。第87頁(yè)/共257頁(yè)#include<iostream.h>#include<string.h>classStudent{//學(xué)生類(lèi)protected:intno;//學(xué)號(hào)
charname[10];//姓名
floatmath,cpp;//數(shù)學(xué)成績(jī)、C++成績(jī)
staticintcount;//累計(jì)總?cè)藬?shù)
staticfloatmsum,csum;//分別累計(jì)數(shù)學(xué)和C++總分
Student*next;public:Student(){}Student(int,char*,float,float,Student*=NULL);floatsum()const//計(jì)算每位學(xué)生的總分
{returnmath+cpp;}第88頁(yè)/共257頁(yè)voidshow1()const//輸出每位學(xué)生的基本信息
{cout<<no<<'\t'<<name<<'\t'<<math<<'\t'<<cpp<<'\t'<<sum()<<endl;}
staticvoidshow2()//輸出每門(mén)課程的平均分
{if(count)cout<<(msum/count)<<'\t'<<(csum/count)<<endl;}
friendclassStuList;//友元類(lèi)};Student::Student(intno,char*name,floatmath,floatcpp,Student*next){Student::no=no;strcpy(Student::name,name);this->math=math;this->cpp=cpp;this->next=next;count++;msum+=math;csum+=cpp;}第89頁(yè)/共257頁(yè)classStuList{Student*head;public:StuList(){head=NULL;}~StuList();voidcreate();//創(chuàng)建鏈表
voidprint()const;//輸出鏈表};StuList::~StuList(){Student*p;while(head){p=head;head=head->next;deletep;}}第90頁(yè)/共257頁(yè)voidStuList::create(){//尾結(jié)點(diǎn)插入法創(chuàng)建單向鏈表
Student*p1,*p2;intno;charname[10];floatmath,cpp;cout<<"輸入學(xué)號(hào),-1表示結(jié)束:";cin>>no;while(no!=-1){cout<<"輸入姓名及數(shù)學(xué)、C++語(yǔ)言成績(jī):",cin>>name>>math>>cpp;p1=newStudent(no,name,math,cpp);if(!head)head=p1,p2=p1;elsep2->next=p1,p2=p1;cout<<"輸入學(xué)號(hào),-1表示結(jié)束:";cin>>no;}}第91頁(yè)/共257頁(yè)voidStuList::print()const{Student*p=head;cout<<"學(xué)號(hào)\t姓名\t數(shù)學(xué)\tC++語(yǔ)言\t總分\n";while(p){p->show1();p=p->next;}cout<<"每門(mén)平均分:\t";Student::show2();}intStudent::count;//定義靜態(tài)數(shù)據(jù)成員并初始化floatStudent::msum,Student::csum;voidmain(){StuListli;li.create();li.print();}第92頁(yè)/共257頁(yè)程序的一次運(yùn)行結(jié)果如下:輸入學(xué)號(hào),-1表示結(jié)束:1
輸入姓名及數(shù)學(xué)、C++語(yǔ)言成績(jī):Tom9095
輸入學(xué)號(hào),-1表示結(jié)束:2
輸入姓名及數(shù)學(xué)、C++語(yǔ)言成績(jī):Sun9983
輸入學(xué)號(hào),-1表示結(jié)束:3
輸入姓名及數(shù)學(xué)、C++語(yǔ)言成績(jī):Pod6353
輸入學(xué)號(hào),-1表示結(jié)束:-1
學(xué)號(hào)姓名數(shù)學(xué)C++語(yǔ)言總分
1Tom90951852Sum99831823Pod6353115
每門(mén)平均分:8477第93頁(yè)/共257頁(yè)第12章運(yùn)算符重載12.1運(yùn)算符重載的基本方法12.2運(yùn)算符重載為成員函數(shù)12.3運(yùn)算符重載為友元函數(shù)12.4幾個(gè)特殊運(yùn)算符的重載12.5運(yùn)算符重載的規(guī)則12.6字符串類(lèi)作業(yè):6~9運(yùn)算符重載:重定義已有運(yùn)算符,完成特定操作,即同一運(yùn)算符根據(jù)不同的運(yùn)算對(duì)象完成不同的操作。運(yùn)算符重載是面向?qū)ο蟪绦蛟O(shè)計(jì)的多態(tài)性之一。C++允許運(yùn)算符重載。第94頁(yè)/共257頁(yè)12.1運(yùn)算符重載的基本方法重載運(yùn)算符的目的:使運(yùn)算符可以直接操作自定義類(lèi)型的數(shù)據(jù)。classComplex{floatreal,imag;public:
Complex(floatr=0,floati=0){real=r;imag=i;}Complexadd(constComplex&c){returnComplex(real+c.real,image+c.image);}};voidmain(){complexc1(3.2,4.6),c2(6.2,8.7),c3;
c3=c1.add(c2);};問(wèn):能否簡(jiǎn)寫(xiě)成c3=c1+c2;答:運(yùn)算符雖能直接操作基本數(shù)據(jù)類(lèi)型的數(shù)據(jù),但對(duì)于自定義類(lèi)型的數(shù)據(jù),若未重載有關(guān)運(yùn)算符,則不能用這些運(yùn)算符操作自定義類(lèi)型的數(shù)據(jù)。第95頁(yè)/共257頁(yè)如何重載運(yùn)算符運(yùn)算符重載函數(shù):為自定義類(lèi)型添加一個(gè)運(yùn)算符重載函數(shù),簡(jiǎn)稱(chēng)運(yùn)算符函數(shù)。這樣當(dāng)該運(yùn)算符操作指定的自定義類(lèi)型數(shù)據(jù)時(shí),系統(tǒng)自動(dòng)調(diào)用該函數(shù)完成指定操作。運(yùn)算符函數(shù)分為:成員運(yùn)算符函數(shù)友元運(yùn)算符函數(shù)。說(shuō)明運(yùn)算符函數(shù)的語(yǔ)法格式:返回值類(lèi)型operator@(參數(shù)表);關(guān)鍵字重載運(yùn)算符,如:+、-等第96頁(yè)/共257頁(yè)舉例為Complex類(lèi)添加一個(gè)完成兩個(gè)Complex類(lèi)型對(duì)象相加的成員運(yùn)算符函數(shù)
Complexoperator+(Complex&c){returnComplex(real+c.real,image+c.image);}設(shè)c1和c2為Complex類(lèi)型的對(duì)象,則當(dāng)遇到表達(dá)式c1+c2時(shí),系統(tǒng)自動(dòng)調(diào)用上面的運(yùn)算符重載函數(shù)完成加法操作。第97頁(yè)/共257頁(yè)12.2運(yùn)算符重載為成員函數(shù)定義格式:
classX{
…
public:
<type>operator@(<Arg>);
…};說(shuō)明:@函數(shù)應(yīng)說(shuō)明為公有的,否則外界無(wú)法使用。系統(tǒng)約定,當(dāng)@函數(shù)為類(lèi)成員時(shí),其第一操作數(shù)為當(dāng)前對(duì)象。因此,若@為一元運(yùn)算符,則參數(shù)表為空;若@為二元運(yùn)算符,則參數(shù)表的參數(shù)為第二操作數(shù)。成員運(yùn)算符函數(shù)的定義方法與普通成員函數(shù)相同。第98頁(yè)/共257頁(yè)例12.1定義復(fù)數(shù)類(lèi),重載加(+)、減(-)、乘(*)、除(/)運(yùn)算符,實(shí)現(xiàn)復(fù)數(shù)的四則運(yùn)算;重載取負(fù)(-)運(yùn)算符,實(shí)現(xiàn)復(fù)數(shù)的取負(fù)操作。#include<iostream.h>classComplex{//復(fù)數(shù)類(lèi)
doublereal,image;public:Complex(doubler=0,doublei=0){real=r;image=i;}voidprint();Complexoperator+(Complex&);//重載+:復(fù)數(shù)+復(fù)數(shù)
Complexoperator-(Complex&);//重載-:復(fù)數(shù)-復(fù)數(shù)
Complexoperator*(Complex&);//重載*:復(fù)數(shù)*復(fù)數(shù)
Complexoperator/(Complex&);//重載/:復(fù)數(shù)/復(fù)數(shù)
Complexoperator-();//重載-:-復(fù)數(shù)};第99頁(yè)/共257頁(yè)voidComplex::print(){if(image<0)cout<<real<<image<<"i\n";elseif(image>0)cout<<real<<’+’<<image<<"i\n";elsecout<<real<<endl;}ComplexComplex::operator+(Complex&c){returnComplex(real+c.real,image+c.image);}ComplexComplex::operator-(
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版木制家具生產(chǎn)加工木工合作合同范本4篇
- 2025版委托檢測(cè)合同書(shū)-光纖網(wǎng)絡(luò)性能檢測(cè)技術(shù)3篇
- 二零二五版水產(chǎn)品電商平臺(tái)大數(shù)據(jù)分析服務(wù)合同2篇
- 2025年度母子公司新能源儲(chǔ)能技術(shù)研發(fā)合作合同3篇
- 《吳組緗天下太平》課件
- 單板加工自動(dòng)化與智能化技術(shù)考核試卷
- 2025版互聯(lián)網(wǎng)醫(yī)療投資項(xiàng)目融資借款合同3篇
- 《物價(jià)上漲時(shí)政》課件
- 2025年度木工工具租賃與施工服務(wù)承包合同4篇
- 2025年兒童玩具連鎖店加盟合同
- 農(nóng)民工工資表格
- 【寒假預(yù)習(xí)】專(zhuān)題04 閱讀理解 20篇 集訓(xùn)-2025年人教版(PEP)六年級(jí)英語(yǔ)下冊(cè)寒假提前學(xué)(含答案)
- 2024年智能監(jiān)獄安防監(jiān)控工程合同3篇
- 2024年度窯爐施工協(xié)議詳例細(xì)則版B版
- 幼兒園籃球課培訓(xùn)
- 【企業(yè)盈利能力探析的國(guó)內(nèi)外文獻(xiàn)綜述2400字】
- 統(tǒng)編版(2024新版)七年級(jí)《道德與法治》上冊(cè)第一單元《少年有夢(mèng)》單元測(cè)試卷(含答案)
- 100道20以?xún)?nèi)的口算題共20份
- 高三完形填空專(zhuān)項(xiàng)訓(xùn)練單選(部分答案)
- 護(hù)理查房高鉀血癥
- 項(xiàng)目監(jiān)理策劃方案匯報(bào)
評(píng)論
0/150
提交評(píng)論