




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第8章類和對象從簡單到復雜人類發展史,是一部從簡單到復雜,從容易到困難的探索歷史以交通工具的生產制作為例說明。任何一個合格的木匠都能獨立制作一輛馬車。復雜的交通工具再優秀的工程師都無法獨立生產一輛汽車甚至一輛自行車。那該怎么辦呢?采用面向對象的設計思想對問題的表述從簡到繁單個變量:反映無關聯的屬性
inta,b,c;變量的集合數組:反映同類型相關屬性inta[10],b[20];結構體:反映相關屬性,可以描述較復雜的事物的屬性(不同類型)Structstudent{
intid;charname[20];
floatscore[5];};問題一:對變量的操作是另外定義的,與變量定義分離。問題二:對于復雜系統的描述,將有大量屬性數據及其相關操作,數據與操作之間的對應關系也十分復雜屬性與操作的集合--在一個類型中定義屬性,同時定義與這些屬性相關的操作問題三:對客觀世界的描述,總是屬性(數據)與性能(動作)相聯系的,在計算機內部如何表達?類“時鐘”類的定義classClock{private:
inthour,minute,second;public:
voidSettime(inth,intm,ints) { hour=h;minute=m;second=s; }
voidGettime(int&h,int&m,int&s) { h=hour;m=minute;s=second; }};從外界對時鐘設置時間,比如鐘表背面的設置按鈕外界獲取時鐘的時間,比如鐘表正面的表盤8.1面向對象程序設計方法概述對象對象的兩個要素:靜態特征:屬性;考慮汽車有哪些屬性?動態特征:行為;考慮汽車有哪些行為?一個系統的多個對象之間通過消息相互聯系。考慮行駛到路口的汽車考到紅燈這個信號(消息)時會產生什么樣的行為?注意:汽車是一個大的對象,它是由許多更小的對象組成的,如,發動機、地盤、輪子等。封裝與信息隱蔽考慮一臺電視機,它里面的結構和工作原理我們知道嗎?對普通的人來說,需要知道嗎?封裝的含義:將有關的數據和操作代碼封裝在一個對象中,形成一個基本的單位,各個對象之間相對獨立,互不干擾。將對象中某些部分對外隱蔽,即隱蔽其內部細節,只留下少量接口,以便與外界聯系,接受外界的消息。電視機的接口抽象什么是汽車?把具有輪子,能滾動前進的陸地交通工具統稱為“車子”。再進一步,把用汽油發動機驅動的車子抽象為“汽車”,把用馬拉的車子抽象為“馬車”,用腳蹬的車子抽象為腳踏車。具有某些相同的屬性和行為類與對象:類是對象的抽象,對象是類的特例,是類的具體表現形式。人小李小周…抽象的概念具體的人繼承與重用現代工業高效的重要原因:重用性,一件工業產品的生產通常都不是從零開始的,總是盡可能利用前有的成果。那么軟件產品呢,是不是也可以實現重用?怎么實現呢?重用要通過繼承機制來實現。繼承車子馬車汽車腳踏車多態性考慮,停在路口的汽車和馬車,當看到左轉向的信號燈由紅燈變為綠燈時,分別拐向機動車道和非機動車道。多態性:由繼承而產生的相關的不同的類,其對象對同一消息會作出不同的響應。8.1.2面向對象程序設計的特點面向過程程序設計:圍繞功能,面向函數;面向對象程序設計:圍繞對象的設計,面向對象;面向對象程序設計,程序設計者的任務:設計所需的各種類和對象,即決定把哪些數據和操作封裝在一起;考慮怎樣向有關對象發送消息,以完成所需的任務。8.1.3類和對象的作用基于對象:Object-Based,以類和對象為基礎,程序的操作時圍繞對象進行的。面向對象:Object-Oriented,在基于對象的基礎上,利用繼承機制和多態性,實現重用性。類是所有面向對象的語言的共同特征,所有面向對象的語言都提供了這種類型一個有一定規模的C++程序是由許多類所構成的一個有一定規模的C++程序在執行時表現為許多相關的對象相互之間的作用8.2類的聲明和對象的定義8.2.1類和對象的關系類與對象的關系如同結構體類型與結構體變量的關系。具體來說,就是:類是對象的抽象,而對象是類的具體實例。類是抽象的,不占用內存,而對象是具體的,占用存儲空間。人小李小周…抽象的概念具體的人8.2.2聲明類類型類聲明方法及例子如下:classClock{private:
inthour,minute,second;public:
voidSettime(inth,intm,ints) { hour=h;minute=m;second=s; }
voidGettime(int&h,int&m,int&s) { h=hour;m=minute;s=second; }};在類里包含了數據成員和操作數據成員的成員函數,實現了把數據和操作封裝在一起。成員訪問限定符,如不指定,則默認為private類類型的聲明,一般形式如下:
class
類名{
private:私有的數據和成員函數;
public:公用的數據和成員函數;
protected: 保護的數據和成員函數;};
inthour;intminute;intsecond;DoorSettimeGettimehour,minute,secondprivatememberhourminutesecond成員訪問限定符public:既可以被本類中的成員函數訪問,也可以被類的作用域內的其他函數訪問。private:只能被本類中的成員函數訪問,在類外(友元類例外,第9章)不能被訪問。(注意理解類外的含義)protected:不能被類外訪問,但可以被派生類的成員函數訪問。成員訪問限定符的聲明次序是任意的。請分析以下例子中各成員的訪問屬性。classClock{private:
inthour;
intminute;
intsecond;…};classClock{
inthour;private:
intminute;
intsecond;…};classClock{
inthour;public:
intminute;
intsecond;…};classClock{private:inthour;intminute;public:intsecond;…};classClock{public:
inthour;private:
intminute;public:
intsecond;…};classClock{private:
inthour,minute,second;public:
voidSettime(inth,intm,ints) {hour=h;minute=m;second=s;}
voidGettime(int&h,int&m,int&s) {h=hour;m=minute;s=second;}};私有成員,只有類內部定義的函數可以訪問。公有成員,類內部、外部定義的函數都可以調用。注意理解“類外”的含義voidmain(){ Clockck;
inth,m,s; ck.Settime(8,15,23);//ck.hour=8;有語法錯誤嗎? ck.Gettime(h,m,s); cout<<"Time:"<<h<<":"<<m<<":"<<s<<endl;}main()相對于Clock類是“外部”的,不能直接訪問Clock內的私有成員,但可以通過調用Clock定義的公有函數,實現對Clock私有成員的設置與數據獲取。理解“類的作用域”voidmain(){ClockCk1;//undeclaredidentifierCk1.Settime(8,12,56);}classClock{private: …public: …};//clock.hclassClock{private: …public: …};//main.cpp#include“clock.h”voidmain(){ClockCk1;//undeclaredidentifierCk1.Settime(8,12,56);}要把頭文件clock.h包含進來Clock類的聲明必須出現在使用之前理解類內部的作用域類是一個自成一體的“小世界”,其中的標識符(包括數據成員和成員函數)作用范圍是類內部:類中的成員可以訪問同一類的其它成員;類內部成員函數中定義的局部變量可以屏蔽同名的數據成員;classA{private:
intx,y;public:
voidf() {
intx;...//A::x被屏蔽 }};8.2.3定義對象的方法與使用結構體類型定義結構體變量類似//方法一classClock{private: …public: …};classClockCk1,Ck2;//方法二classClock{private: …public: …}Ck1,Ck2;//方法三class{private: …public: …}Ck1,Ck2;關于對象數據成員的初始化注意:與結構體變量初始化不同的是不能在定義對象時對對象的私有數據成員用直接賦值的形式進行初始化。對對象的私有成員的初始化要使用構造函數(第9章)來實現。classClock{private: …public: …};classClock=(10,8,24);//錯誤使用對象(及其成員)使用對象的成員(包括數據成員和成員函數)方法,使用成員運算符:對象.成員Clockck1,ck2;ck1.Settime(9,23,42);inthh,mm,ss;ck1.Gettime(hh,mm,ss);給對象ck1中的私有數據成員hour,minute,second賦值獲取對象ck1中的私有數據成員hour,minute,second的數據通過調用類的公有成員函數訪問類中的私有成員。函數參數傳遞使用哪種方式?8.2.4類和結構體類型的異同在C++里,從功能上說,類類型和結構體類型完全一樣(在結構體里也可以定義函數),在C++保留結構僅僅是為了與C語言兼容。用struct聲明的類和用class聲明的類的區別:用struct聲明的類,其成員訪問屬性默認為public,用class聲明的類,其成員訪問屬性默認為private。一般來說,對簡單的類(不包含成員函數),用struct來定義,反之,用class來定義。//沒有對成員的訪問屬性//做顯式聲明,默認為publicstructStudent{intnum;
charname[20];charsex;
voiddisplay(){cout<<num<<endl;cout<<name<<endl;cout<<sex<<endl;}}//沒有對成員的訪問屬性//做顯式聲明,默認為privateclassStudent{intnum;
charname[20];
charsex;
voiddisplay(){cout<<num<<endl;cout<<name<<endl;cout<<sex<<endl;}}8.3類的成員函數8.3.1成員函數的性質接口函數:需要被外界調用的成員函數,必須設置為public;工具函數:只被類中其他函數調用,不被外界調用,一般來說應該設置為private;接口函數與工具函數classClock{private:
inthour,minute,second; voidjudge(){
if(hour>23||hour<0)hour=0;
if(minute>59||minute<0)minute=0;
if(second>59||second<0)second=0; }public:
voidSettime(inth,intm,ints) {hour=h;minute=m;second=s;judge();}
voidGettime(int&h,int&m,int&s) {h=hour;m=minute;s=second;}};工具函數,只被Settime()函數調用8.3.2在類外定義成員函數成員函數可以直接在類里定義,也可以先在類里聲明,然后在類外定義。classClock{private:
inthour,minute,second;public:
voidSettime(inth,intm,ints) {hour=h;minute=m;second=s;}
voidGettime(int&h,int&m,int&s);//聲明};void
Clock::Gettime(int&h,int&m,int&s)//定義{h=hour;m=minute;s=second;}作用域運算符:優先級最高作用域運算符正確使用作用域運算符:在類內部聲明和定義成員函數時不需要加作用域運算符;在類外部定義類的成員函數時,需要加作用域運算符;如果在外部定義函數時加了作用域運算符::,但在前面沒有加類名,或者既無類名又無作用域運算符,定義的都是普通的全局函數,如:::display()或display()8.3.3inline成員函數P97內置函數(inline函數)提出原因:函數調用開銷(保護現場和恢復現場)比較大。適用范圍:代碼簡單且頻繁調用的函數。(現在的編譯系統已經能夠識別這類函數并自動將函數設置為內置函數,并不取決與用戶是否將函數聲明為內置。)實現方法:在編譯時直接將內置函數的代碼嵌入到函數調用處。inta[1000],b[1000];…for(inti=1,sum=0;i<1000;i++) sum+=max(a[i],b[i]);intmax(inta,intb){
if(b>a)returnb;
else
returna;}類的成員函數的內置處理出發點:也是為了減小時間開銷。處理方法:對于在類里面定義的成員函數,默認為內置函數,因此inline可以省略對于在類外面定義的成員函數,并不默認為inline函數,必須顯式地說明。inline
voidClock::Gettime(int&h,int&m,int&s){ h=hour;m=minute;s=second;}8.3.4成員函數的存儲方式聲明類之后,用類去定義對象,編譯系統要為對象分配存儲空間。分配方法一:每定義一個對象,分別為該對象的數據和函數代碼分配存儲空間。缺點:浪費存儲空間。(不采用)Ck1.Settime()Ck1.Gettime()Ck1.hourCk1.minuteCk1.secondCk2.Settime()Ck2.Gettime()Ck2.hourCk2.minuteCk2.second…Ck10.Settime()Ck10.Gettime()Ck10.hourCk10.minuteCk10.second注意到:同一個類的每個對象數據值不相同,但成員函數的代碼是完全一樣的。方法二:只用一段存儲空間來存儲同一個類不同對象的成員函數代碼,在調用各對象的函數時,都去調用這個共用的函數代碼。對象的數據成員存儲在程序數據區對象的函數成員統一存儲在程序代碼區Settime()Gettime()Ck1.hourCk1.minuteCk1.secondCk2.hourCk2.minuteCk2.secondClockck1,ck2;//用sizeof()測試問題:當調用成員函數時,成員函數怎么知道當前操作的是哪個對象的數據?Clockck1,ck2;……Ck1.Settime(10,34,23);Ck2.Settime(23,12,54);Settime()Gettime()Ck1.hourCk1.minuteCk1.secondCk2.hourCk2.minuteCk2.second調用(10,34,23)調用(23,12,54)使用哪一套?需要有一個參數來表示當前操作的是哪個對象this指針this指針(P281)在對象調用成員函數時,除了傳遞函數參數外,還傳遞一個隱含的指針--this指針,指向對象本身。當調用ck1的成員函數,this指針就指向ck1,當調用ck2的成員函數,this指針就指向ck2。在成員函數中,所有對數據成員的訪問都會(隱含地)加上一個this指針:hour this->hourminutethis->minutesecondthis->secondclassClock{private:
inthour,minute,second;public:
voidSettime(inth,intm,ints) { this->hour=h; this->minute=m; this->second=s;}
voidGettime(int&h,int&m,int&s);//聲明};void
Clock::Gettime(int&h,int&m,int&s)//定義{h=hour;m=minute;s=second;}classClock{private:
inthour,minute,second;public:
voidSettime(inth,intm,ints) { hour=h; minute=m; second=s;}
voidGettime(int&h,int&m,int&s);//聲明};void
Clock::Gettime(int&h,int&m,int&s)//定義{h=hour;m=minute;s=second;}Settime()Ck1.hourCk1.minuteCk1.secondCk2.hourCk2.minuteCk2.second調用(10,34,23,this(ck2))調用(23,12,54,this(ck1))……Ck1.Settime(23,12,54);Ck2.Settime(10,34,23);8.4對象成員的引用通過對象名和成員運算符訪問對象中的成員通過指向對象的指針訪問對象中的成員通過對象的引用變量訪問對象中的成員例如:stud1.num=1001;//假設num已定義為公用的整型數據成員例如:class
Time{public://數據成員是公用的
inthour;
intminute;};Timet,*p;//定義對象t和指針變量pp=&t;//使p指向對象tcout<<p->hour;//輸出p指向的對象中的成員hour例如:class
Time{public://數據成員是公用的
inthour;
intminute;};Timet1;//定義對象t1Time&t2=t1;//定義Time類引用變量t2,并使之初始化為t1cout<<t2.hour;//輸出對象t1中的成員hour說明:同一類型的對象可整體賦值,但使用要慎重(P291介紹對象拷貝)。intmain(){ClockCk1,Ck2;Ck1.Settime(8,12,20);Ck2=Ck1;//請慎重使用
inth,m,s;Ck2.Gettime(h,m,s);cout<<"hour:"<<h<<"minute:"<<m<<"second:"<<s<<endl;
return0;}8.5類的封裝性和信息隱蔽面向對象程序設計方法中,封裝性和信息隱蔽的目的:為保證安全性,盡可能不讓類外的函數直接使用類的數據成員;為保密起見,盡可能不公開成員函數的代碼;為使用方便和減小開銷,在使用類時只需加載盡可能少的文件,和避免重復加載。實現的原則:公用接口和私有實現的分離類聲明和成員函數定義的分離8.5.1公用接口與私有實現的分離一般把類的數據成員設置為私有,不允許外界直接訪問數據成員,公用成員函數充當使用類的公用接口。公用成員函數的代碼一般是不公開的,其中實現的細節是隱蔽的,稱為私有實現。
inthour;intminute;intsecond;DoorSettimeGettimehour,minute,secondprivatememberhms8.5.2類聲明和成員函數定義的分離出發點:把類的聲明和成員函數的實現分別放在不同的文件里。頭文件的處理:如果在程序中需要使用到該類,只要把頭文件包含進來就可以了。實現文件的處理:編譯成目標文件一次性加載進來。//student.hstructStudent{public:
voiddisplay();private:
intnum;
charname[20];
charsex;}//student.cpp#include<iostream>#include"student.h“usingnamespacestd;voidStudent::display(){cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl;}//main.cpp#include<iostream>#include"student.h"usingnamespacestd;voidmain(){Studentstud;stud.display();
return0;}使用類的接口文件包含預處理中,用尖括號(<>)和雙撇號(“”)的區別(P130):用尖括號:編譯系統到系統目錄中尋找要包含的文件。系統目錄就是安裝C++系統的目錄。雙撇號:編譯系統先到指定目錄中去找要包含的文件,如果沒有指定目錄,則在當前目錄下找;如果找不到,再到系統目錄下去找。//main.cpp#include<iostream>#include<student.h>//錯誤voidmain(){Studentstud;stud.display();return0;}類庫類庫:把若干個常用的功能相近的類聲明集中在一起,形成類庫。C++編譯器提供的標準類庫;如標準輸入流對象cin就是在標準類庫中定義的。還有常用的數學函數也是由標準類庫提供的,其聲明在math.h頭文件中給出。用戶根據自己的需要或出于商業的目的開發的用戶類庫,稱為自定義類庫。8.5.3對象、方法、消息類的成員函數:方法調用成員函數的程序語句:消息inth,m,s;Ck1.Gettime(h,m,s);給對象Ck1發出一個消息,通知它執行其中的Gettime方法,得到其私有成員hour,minute,second,保存到變量h,m,s里。8.6類和對象的簡單應用舉例書上的例子例8.1,類Time不含函數成員。例8.2程序(a):多個Time對象,在主函數中依次對其成員進行賦值,然后輸出;程序(b):在主函數中定義set_time函數,實現對Time對象成員的賦值,定義show_time函數,實現輸出Time對象的成員;程序(c):set_time函數改為通過參數實現對Time對象成員的賦值,并且是默認參數。例8.3,用含成員函數的Time類實現例8.2例8.4,用類的方法實現找出一個整數數組中的元素的最大值。課后習題6需要求3個長方體的體積,請編寫一個基于對象的程序。對象的數據成員包括length,width,height。要求用成員函數實現以下功能:由鍵盤分別輸入3個長方體的長、寬、高;計算長方體的體積;輸出3個長方體的體積。分析:類的3個數據成員都是私有的;成員函數get_value實現從鍵盤上輸入3個成員數據;成員函數volume實現計算長方體的體積;成員函數display實現輸出長方體的體積;classBox{public:
voidget_value();
floatvolume();
voiddisplay();private:
floatlengh,width,height;};voidBox::get_value(){cout<<"pleaseinputlengh,width,height:";cin>>lengh;cin>>width;cin>>height;}floatBox::volume(){return(lengh*width*height);}voidBox::display(){cout<<volume()<<endl;}intmain(){Boxbox1,box2,box3;box1.get_value();cout<<"volmueofbax1is";box1.display();box2.get_value();cout<<"volmueofbax2is";box2.display();box3.get_value();cout<<"volmueofbax3is";box3.display();
return0;}改進:再定義一個成員,記錄長方體的體積classBox{public:
voidget_value();
floatvolume();
voiddisplay();private:
floatlengh,width,height;
floatvol;};voidBox::get_value(){cout<<"pleaseinputlengh,width,height:";cin>>lengh;cin>>width;cin>>height;}floatBox::volume(){vol=lengh*width*height;}voidBox::display(){cout<<vol<<endl;}Person類新建控制臺工程(Win32ConsoleApplication)頭文件person.h#include<iostream.h>#include<string.h>classPerson{private:
charName[20];
unsignedAge;
charSex;public:
voidRegister(constchar*,int,char);//為數據成員賦值
voidGetName(char*na) //取得數據成員Name {strcpy(na,Name);};
intGetAge() //取得數據成員Age {return(Age);};
charGetSex(); //取得數據成員sex {return(Sex);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑垃圾運輸保險合同建議
- 汽車美容院勞務合同
- 糧油產品物流合同模板
- 腦膜瘤的術前術后護理
- 自上而下管理課件
- 淋巴漏的護理措施
- 胃腸減壓護理操作
- 環衛工夏季安全作業
- 電工登高培訓課件
- 2024深圳市開放職業技術學校工作人員招聘考試及答案
- 2025年浙江省初中名校發展共同體中考語文一模試卷附參考答案
- 2025年食安食品考試題及答案
- 2025年租賃料場協議
- 2025年北森題庫測試題及答案
- 2025年必考保安證試題及答案
- 中國大唐集團有限公司陸上風電工程標桿造價指標(2023年)
- 茶館里的政治:揭秘《茶館》背后的歷史
- 醫院保安服務方案投標文件(技術方案)
- 危機公關服務合同范本
- 跨學科實踐活動5探究土壤酸堿性對植物生長的影響教學設計-2024-2025學年九年級化學魯教版下冊
- 保證食品安全的規章制度清單
評論
0/150
提交評論