




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第3章VC程序核心——類與對(duì)象
教學(xué)要點(diǎn)
本章內(nèi)容主要包括面向?qū)ο蟪绦蛟O(shè)計(jì)特點(diǎn)、結(jié)構(gòu)和類定義、類的成員變量和成員函數(shù)定義,類的在類定義中的體現(xiàn),利用繼承性派生新的類,類的多態(tài)性。要求了解類的各種繼承方式、抽象類的概念與使用。熟悉類的定義和如何實(shí)現(xiàn)類的封裝性、繼承性和多態(tài)性掌握構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用特點(diǎn)、由類實(shí)例化對(duì)象的方法,熟練掌握通過虛函數(shù)、繼承關(guān)系和指向基類的指針實(shí)現(xiàn)多態(tài)性的方法。
1第3章:VC程序設(shè)計(jì)核心-類與對(duì)象 3.1面向?qū)ο蟪绦蛟O(shè)計(jì)特點(diǎn) 3.2面向?qū)ο蟮幕?3.3對(duì)象 3.4類的繼承與派生 3.5類的多態(tài)性第3章目錄2第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1 面向?qū)ο蟪绦蛟O(shè)計(jì)特點(diǎn) 3.1.1 抽象 3.1.2 封裝 3.1.3 繼承 3.1.4 多態(tài) 3.1.5 以VC作為面向?qū)ο蟪绦蛟O(shè)計(jì)的原因 3.1.6*面向?qū)ο蟪绦蛟O(shè)計(jì)的優(yōu)點(diǎn)3第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1.1 抽象抽象是指從具體的實(shí)例中抽取出來共同的性質(zhì)并加以描述的過程,它忽略了一個(gè)主題中與當(dāng)前目標(biāo)無關(guān)的那些方面,以便更充分地注意與當(dāng)前目標(biāo)有關(guān)的方面。
4第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1.2封裝
封裝指的是將方法和數(shù)據(jù)放于同一對(duì)象中,使得對(duì)數(shù)據(jù)的存取只能通過該對(duì)象本身的方法來進(jìn)行。主要思想是將數(shù)據(jù)(數(shù)據(jù)成員)及處理這些數(shù)據(jù)的相應(yīng)函數(shù)(成員函數(shù))封裝到類class中(C++的一種新的定義數(shù)據(jù)類型的方法),而使用類的變量則稱為對(duì)象(object),在對(duì)象內(nèi),只有屬于該對(duì)象的成員函數(shù)才可以存取該對(duì)象的數(shù)據(jù)成員。這樣,其他函數(shù)就不會(huì)破壞到它的內(nèi)容,從而起到保護(hù)和隱藏?cái)?shù)據(jù)的效果。5第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1.3 繼承繼承是一種聯(lián)結(jié)類與類之間的層次模型,它允許和鼓勵(lì)類的重用,提供了一種明確表達(dá)共性的方法。一個(gè)新類可以從現(xiàn)有的類中派生,這個(gè)過程稱為類繼承
繼承性很好地解決了軟件的可重用問題
6第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1.4 多態(tài)多態(tài)性指的是同一消息被不同的對(duì)象接收后被解釋為不同含義的能力,也就是一個(gè)接口名稱具有多種功能。
多態(tài)性語言具有語言靈活、抽象、行為共享、代碼共享的優(yōu)勢(shì),很好的解決了應(yīng)用程序函數(shù)同名的問題。7第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1.5 以VC作為面向?qū)ο?/p>
程序設(shè)計(jì)的原因1.VC提供面向?qū)ο蟮耐暾Z法與語義2.VC還是一種結(jié)構(gòu)化的程序設(shè)計(jì)語言3.VC中的MFC是理解面向?qū)ο笳Z法與語義的最好平臺(tái)8第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.1.6 面向?qū)ο蟪绦?/p>
設(shè)計(jì)的優(yōu)點(diǎn)面向?qū)ο缶幊痰暮锰幾蠲黠@的是使代碼的可重用性大大提高,使程序員擺脫了重復(fù)性的勞動(dòng)。面向?qū)ο缶幊讨械膶?duì)象比較獨(dú)立,它給外界提供了統(tǒng)一的接口,當(dāng)對(duì)象一旦建立,就可以重復(fù)使用。采用面向?qū)ο缶幊痰暮锰幘褪谴a的可擴(kuò)充性。9第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2 面向?qū)ο蟮幕?3.2.1從結(jié)構(gòu)到類 3.2.2類的定義
3.2.3類的屬性——成員變量 3.2.4類的行為——成員函數(shù) 3.2.5類成員的訪問控制 3.2.6*類的深入理解 10第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2.1 從結(jié)構(gòu)到類 1.結(jié)構(gòu)體
VC不僅提供了大量預(yù)先定義的數(shù)據(jù)類型,而且還支持自定義的數(shù)據(jù)類型。
結(jié)構(gòu)就是把相互關(guān)聯(lián)的一些基本數(shù)據(jù)類型的元素組成一個(gè)新的獨(dú)立統(tǒng)一體。
11第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-1】定義一個(gè)職工Employee結(jié)構(gòu)數(shù)據(jù)類型,它包括姓名、工資、地址、移動(dòng)電話。structEmployee{charname[9];floatsalary;charaddress[40];charmobile[12];};定義一個(gè)結(jié)構(gòu)體,事實(shí)上是定義了一種數(shù)據(jù)類型,程序并不會(huì)給類型分配內(nèi)存,內(nèi)存分配是發(fā)生在結(jié)構(gòu)體變量上12第3章:VC程序設(shè)計(jì)核心-類與對(duì)象#include"iostream.h"#include"string.h"voidmain(){structEmployeeEmployeeA;strcpy(EmployeeA.name,"滅絕師太");EmployeeA.salary=168.47;strcpy(EmployeeA.address,"峨眉山上");strcpy(EmployeeA.mobile,"");cout<<EmployeeA.name<<"已經(jīng)領(lǐng)上工資了,其數(shù)目是"<<EmployeeA.salary<<endl;cout<<"要想拜謁她,請(qǐng)到"<<EmployeeA.address<<"或直接傳呼"<<EmployeeA.mobile<<endl;}【例3-2】定義一個(gè)具體職工EmployeeA,并對(duì)該職工進(jìn)行賦值。程序的主文件名為DefStru.cpp。
13第3章:VC程序設(shè)計(jì)核心-類與對(duì)象程序的運(yùn)行結(jié)果是:滅絕師太已經(jīng)領(lǐng)上工資了,其數(shù)目是168.47要想拜謁她,請(qǐng)到峨眉山上或直接傳呼
14第3章:VC程序設(shè)計(jì)核心-類與對(duì)象2.類類是從一個(gè)個(gè)具體的事物中把共同特征抽取出來形成的一個(gè)概念,它反映了事物之間的共性
在C++中,在類的定義中,不僅有反映事物屬性的成員變量,還有反映屬性操作的成員函數(shù)。類一種自定義數(shù)據(jù)類型。15第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2.2 類的定義在C++中類的定義方式為:class類名{private:
私有數(shù)據(jù)及成員函數(shù);protected:
保護(hù)數(shù)據(jù)及成員函數(shù);public:
公有數(shù)據(jù)及成員函數(shù);};16第3章:VC程序設(shè)計(jì)核心-類與對(duì)象class是類定義符,類名是一種標(biāo)識(shí)符,它的命名規(guī)則與變量名的命名規(guī)則相同。一對(duì)花括號(hào)內(nèi)是類的說明部分,說明該類的成員。類的成員包括成員變量和成員函數(shù)兩部分。上述在類的成員變量和成員函數(shù)前面出現(xiàn)的關(guān)鍵字——public(公有)、private(私有)或protected(保護(hù))表示成員的訪問屬性。在類中聲明的成員變量若不特別指明,都被視為私有類型。私有類型的數(shù)據(jù)只允許類本身聲明的函數(shù)對(duì)其進(jìn)行存取,而類外部的任何函數(shù)都不能訪問。公有類型的成員可以被任何函數(shù)來訪問,它們是類與外部的接口。
17第3章:VC程序設(shè)計(jì)核心-類與對(duì)象類的定義反映了對(duì)類的描述,定義一個(gè)類就是定義一種數(shù)據(jù)類型,把握類的定義首先要掌握類中包含反映事物屬性的那些成員變量和反映事物操作的那些成員函數(shù)。
【例3-3】定義一個(gè)職工TEmployee類,它包括姓名、工資、地址、移動(dòng)電話數(shù)據(jù)成員和兩個(gè)成員函數(shù),分別實(shí)現(xiàn)輸入職工數(shù)據(jù)和顯示職工屬性。18第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classTEmployee{public: voidinput(char*name,floatsalary,char*address,char*mobile); voiddisplay();private: charm_name[9]; floatm_salary; charm_address[40]; charm_mobile[12];};19第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-4】定義一個(gè)交通工具類TVehicle,它具有輪子個(gè)數(shù)、載重兩個(gè)數(shù)據(jù)成員和三個(gè)成員函數(shù),分別實(shí)現(xiàn)輸入交通工具的輪子和載重、取輪子個(gè)數(shù)和載重。
classTVehicle{public:voidInitialize(intwheels,floatweight);//交通工具的初始化intGetWheels(void);//取輪子個(gè)數(shù)floatGetWeight(void);//取載重private:intm_wheels;//輪子個(gè)數(shù)floatm_weight;//載重};20第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2.3 類的屬性——成員變量1.類的普通成員變量
類的普通成員變量指的是類的數(shù)據(jù)域的數(shù)據(jù)類型是基本數(shù)據(jù)類型如int、char、float等。例如前面定義的雇員類TEmployee,它的所有的數(shù)據(jù)域都是普通的成員變量。2.類的對(duì)象成員變量
類的對(duì)象成員變量指的是類的數(shù)據(jù)域的數(shù)據(jù)類型是其它的類,這些類可以是自定義的,也可以是一些類庫中的類(如后面所說的MFC類庫)。
21第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-5】在前面定義的職工TEmployee類中增加一個(gè)對(duì)象成員出生時(shí)間m_Birthday,它是MFC中的一個(gè)類CTime。
classTEmployee{public: voidinput(char*name,floatsalary,char*address,char*mobile); ……private: charm_name[9]; …… CTimem_birthday;//定義對(duì)象成員m_birthday };22第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
由于CTime類是MFC中的一個(gè)類,在使用該類庫中的類時(shí),必須在類的定義文件開始加上#include<afx.h>語句,并對(duì)VC當(dāng)前開發(fā)的工程進(jìn)行一些設(shè)置(點(diǎn)擊菜單Projects|Setting,打開General選項(xiàng)卡,在MicrosoftFoundationClasses列表框中選擇UseMFCinaSharedDLL)。
23第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-6】看看CTime類中的對(duì)象成員,體會(huì)微軟軟件開發(fā)師的杰作,體會(huì)對(duì)象成員的作用(這些代碼在VisualStudio\vc98\mfc\include\afx.h頭文件中)。
classCTime{public:
//Constructors staticCTimePASCALGetCurrentTime();……
private: time_tm_time;//類的對(duì)象成員};24第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.類的靜態(tài)成員變量靜態(tài)成員變量則不同于一般的類的成員變量。當(dāng)一個(gè)類定義多個(gè)對(duì)象時(shí),所有對(duì)象的靜態(tài)成員變量占用同一個(gè)內(nèi)存空間,也就是說靜態(tài)成員變量對(duì)類的所有對(duì)象只有一份,不同的對(duì)象使用相同的成員變量。應(yīng)用靜態(tài)數(shù)據(jù)成員實(shí)現(xiàn)了數(shù)據(jù)的共享,使類的各個(gè)對(duì)象中可以進(jìn)行消息的傳遞,同時(shí)靜態(tài)數(shù)據(jù)成員不會(huì)破壞數(shù)據(jù)的封裝性,有利于數(shù)據(jù)的安全通信。
25第3章:VC程序設(shè)計(jì)核心-類與對(duì)象從形式上看,靜態(tài)成員變量是在一個(gè)類的成員變量定義前加上關(guān)鍵詞static而構(gòu)成的變量;從存儲(chǔ)角度上看,靜態(tài)成員變量在整個(gè)類上只保留一份,即該類的任何對(duì)象都共享該靜態(tài)成員變量;從作用域來看,靜態(tài)成員變量可看作類的公共變量;靜態(tài)成員變量屬于一個(gè)類而不屬于該類的任何對(duì)象,所以,在類外調(diào)用靜態(tài)成員變量時(shí),必須要用“類名::”作為限定詞。26第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-7】一個(gè)含有類的靜態(tài)成員變量的實(shí)例:某班級(jí)有三個(gè)同學(xué)A、B、C,該班有班費(fèi)1000元。每個(gè)人都可以訪問班級(jí)的班費(fèi),當(dāng)A花去班費(fèi)中的錢時(shí),B、C得到的班費(fèi)就少了,同樣,當(dāng)B花去班費(fèi)中的錢時(shí),A、C得到的班費(fèi)就少了,因而應(yīng)將班費(fèi)設(shè)置為靜態(tài)成員變量。它的特點(diǎn)是該類的每個(gè)對(duì)象都可以訪問,屬于類的公共變量。
27第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classTStudent{private: charm_Name[6]; staticintm_ClassMoney;//m_ClassMoney為靜態(tài)成員變量,保存班費(fèi)public: voidInitStudent(char*); voidExpendMoney(int); staticvoidShowMoney();};intTStudent::m_ClassMoney=1000;//靜態(tài)成員變量的初始化
28第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-8】了解應(yīng)用程序類CWinApp公有的成員變量
CwinApp是Windows的一個(gè)應(yīng)用程序類,它里面的一些公有的成員變量在程序中經(jīng)常要使用。m_pszAppName:應(yīng)用程序的名稱(包含路徑)。m_hInstance:應(yīng)用程序的當(dāng)前實(shí)例。m_hPrevInstance:應(yīng)用程序的前一個(gè)實(shí)例。m_nCmdShow:應(yīng)用程序主窗口的最初何顯示方式(最大化、最小化等)。m_pMainWnd:指向應(yīng)用程序主窗口的指針變量。m_pszExeName:應(yīng)用程序的模塊名稱(不包含路徑)。29第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2.4 類的行為——成員函數(shù)
當(dāng)成員函數(shù)的函數(shù)體代碼較短時(shí),可以在定義類時(shí)直接定義成員函數(shù),即在類內(nèi)定義成員函數(shù)。但當(dāng)成員函數(shù)函數(shù)體較復(fù)雜時(shí),可以在類體外定義成員函數(shù),但必須在類內(nèi)對(duì)成員函數(shù)進(jìn)行聲明。
1.類的普通成員函數(shù)
【例3-9】在前面定義的職工TEmployee類中有一個(gè)輸入職工姓名、工資等屬性的成員函數(shù)input(),通過它實(shí)現(xiàn)職工對(duì)象的初始化。另外還有一個(gè)顯示職工信息的成員函數(shù)diplay(),這些函數(shù)在類體外進(jìn)行定義:
30第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classTEmployee{public: voidinput(char*name,floatsalary,char*address,char*mobile); voiddisplay(); private: charm_name[9]; …};voidTEmployee::input(char*name,floatsalary,char*address,char*mobile){ strcpy(m_name,name);//字符串賦值必須通過字符串拷貝來實(shí)現(xiàn)
m_salary=salary; strcpy(m_address,address); strcpy(m_mobile,mobile);}
31第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidTEmployee::display(){ cout<<"NameIs"<<m_name<<endl; cout<<"SalaryIs"<<m_salary<<endl; cout<<"AddressIs"<<m_address<<endl; cout<<"mobileIs"<<m_mobile<<endl;}說明:在類體外定義成員函數(shù)時(shí)必須使用作用域運(yùn)算符“::”來指明成員函數(shù)所屬的類,在類體內(nèi)訪問成員函數(shù)時(shí),若未指明所屬的類,則默認(rèn)是這個(gè)類的成員函數(shù),若要訪問該類之外的其它類的成員函數(shù),則必須指名該成員函數(shù)所屬的類。32第3章:VC程序設(shè)計(jì)核心-類與對(duì)象2.類的靜態(tài)成員函數(shù)靜態(tài)成員函數(shù)僅屬于一個(gè)類而不屬于該類的任何對(duì)象,因此它不通過對(duì)象直接調(diào)用,而是與類相聯(lián)系的。靜態(tài)成員函數(shù)中沒有this指針,并且靜態(tài)成員函數(shù)中只能訪問靜態(tài)成員變量,在類外調(diào)用靜態(tài)成員函數(shù)時(shí)應(yīng)使用以下方式:類名::靜態(tài)成員函數(shù)名(參數(shù)列表);33第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
【例3-10】一個(gè)含有靜態(tài)成員函數(shù)的其使用。程序的主文件為StaticMember.cpp。
#include"iostream.h"#include<string.h>classTStudent{private: charm_Name[6]; staticintm_ClassMoney;//m_ClassMoney為靜態(tài)成員變量,保存班費(fèi)public: voidInitStudent(char*); voidExpendMoney(int); staticvoidShowMoney();//靜態(tài)成員函數(shù)};34第3章:VC程序設(shè)計(jì)核心-類與對(duì)象intTStudent::m_ClassMoney=1000;//靜態(tài)成員變量的初始化voidTStudent::InitStudent(charname[]){ strcpy(m_Name,name);}voidTStudent::ExpendMoney(intmoney){ m_ClassMoney-=money;//班費(fèi)為原先的減去花費(fèi)的}voidTStudent::ShowMoney(){ cout<<"班費(fèi)還剩余"<<m_ClassMoney<<endl;}35第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidmain(){ TStudentstu[3];//定義三個(gè)學(xué)生
stu[0].InitStudent("marry");stu[1].InitStudent("sunny"); stu[2].InitStudent("jahn"); stu[0].ExpendMoney(100); stu[0].ShowMoney();//作用等同于TStudent::ShowMoney(); stu[1].ExpendMoney(100); stu[1].ShowMoney();//作用等同于TStudent::ShowMoney(); stu[2].ExpendMoney(100); stu[2].ShowMoney();//作用等同于TStudent::ShowMoney();}36第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.類的虛成員函數(shù)從形式上看,虛函數(shù)是在一個(gè)函數(shù)的定義前面加上關(guān)鍵詞virtual而構(gòu)成的函數(shù)。將函數(shù)定義為虛函數(shù)后,可以達(dá)到動(dòng)態(tài)聯(lián)編的效果
37第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-11】一個(gè)含有虛函數(shù)的類。classTPoint//定義一個(gè)點(diǎn)類{private: floatx,y;//x為橫坐標(biāo),y為縱坐標(biāo)public: voidPoint(floati,floatj) {x=i;y=j;}//構(gòu)造函數(shù)
virtualfloatarea(){return0.0;}//求面積的虛函數(shù)};38第3章:VC程序設(shè)計(jì)核心-類與對(duì)象4.MFC中類CString的常見操作下面以在第二篇中常用的一個(gè)字符串類CString為例來說明類的成員函數(shù)功能。CString的主要成員函數(shù)如下:(1)
GetLength:返回CString對(duì)象中的字符數(shù)。(2)
IsEmpty:測(cè)試一個(gè)CString對(duì)象是否空。(3)
Empty:將一個(gè)字符數(shù)的長(zhǎng)度強(qiáng)制為0。(4)
GetAt:返回給定位置上的字符。(5)
SetAt:設(shè)置給定位置上的字符。(6)
Mid:提取一個(gè)字符串的中間部分。
39第3章:VC程序設(shè)計(jì)核心-類與對(duì)象請(qǐng)看下例:(7)Left:提取一個(gè)字符串的左邊部分。(8)Right:提取一個(gè)字符串的右邊部分。(9)MakeUpper:將字符串中的所有字符轉(zhuǎn)換為大寫字符。(10)MakeLower:將字符串中的所有字符轉(zhuǎn)換為小寫字符。(11)Find:在一個(gè)較大的字符串中查找某一個(gè)字符串。(12)GetBuffer:返回一個(gè)指向CString對(duì)象的指針。40第3章:VC程序設(shè)計(jì)核心-類與對(duì)象#include"iostream.h"#include"afx.h"http://CString的頭文件voidmain(){CStringStr1="VC++實(shí)用教程";
CStringStr2="出版商:電子工業(yè)出版社\n";CStringStr3=Str1+Str2;CStringStr4="出版社";cout<<Str3.GetBuffer(0);//取字符串的首地址【例3-12】CString的使用實(shí)例。該程序的主文件為StringTest.cpp41第3章:VC程序設(shè)計(jì)核心-類與對(duì)象比較c*c*cif(Str1.Compare(Str2))//字符串比較
cout<<"字符串Str1與Str2不相同\n";Str3=Str1.Left(2)+Str1.Right(4);//提取字符串cout<<Str3.GetBuffer(0)<<endl;if(Str2.Find(Str4)>0)//利用成員函數(shù)Find查找子串
cout<<"在Str2中找到子串Str4\n";}程序運(yùn)行結(jié)果為:VC++實(shí)用教程出版商:電子工業(yè)出版社字符串Str1與Str2不相同VC教程在Str2中找到子串Str442第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2.5 類成員的訪問控制類的主要作用是實(shí)現(xiàn)對(duì)數(shù)據(jù)和操作的封裝
對(duì)類的成員訪問必須有所限制,根據(jù)訪問權(quán)限不同可將類的訪問控制分為公有(public)、受保護(hù)(protected)和私有(private)三種方式如果未加說明,則默認(rèn)的訪問控制為private。
請(qǐng)看下例:43第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-13】訪問控制實(shí)例。該程序的主文件為AccessControl.cpp#include<iostream.h>#definePI3.14159classcircle{public: voidset(intr) {radius=r; } floatarea();private: floatradius;};floatcircle::area(){ return(PI*radius*radius);}44第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidmain(){ intradius;circleMyCircle; cout<<"請(qǐng)輸入圓的半徑:";
cin>>radius; MyCircle.set(radius); //正確,因?yàn)槌蓡T函數(shù)set()為公有成員
cout<<"該圓的面積為:"<<MyCircle.area()<<endl;//正確,因?yàn)槌蓡T函數(shù)area()為公有成員 //c.radius=3.3;//錯(cuò)誤,類不能對(duì)私有成員直接進(jìn)行訪問}45第3章:VC程序設(shè)計(jì)核心-類與對(duì)象類的訪問控制實(shí)質(zhì)上反映了類對(duì)其成員的封裝程度類的訪問控制實(shí)質(zhì)上反映了類對(duì)其成員的封裝程度
當(dāng)成員被聲明為public時(shí),它可以被外部類的對(duì)象訪問,也可以被派生類的對(duì)象訪問;當(dāng)成員被聲明為protected時(shí),它不能被外部類的對(duì)象訪問,但可以被派生類的對(duì)象訪問;當(dāng)成員被聲明為private時(shí),它既不能被外部類的對(duì)象訪問,也不能被派生類的對(duì)象訪問,只能被本類的成員函數(shù)訪問。不管哪一種訪問類型定義的成員,都可以被它所屬類的成員函數(shù)所訪問。
46第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.2.6* 類的深入理解1.類是一種數(shù)據(jù)類型2.類是一個(gè)代數(shù)系統(tǒng)
3.類是實(shí)現(xiàn)面向?qū)ο筇匦缘妮d體
47第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.3 對(duì)象 3.3.1對(duì)象的聲明 3.3.2對(duì)象的使用 3.3.3對(duì)象的初始化——構(gòu)造函數(shù) 3.3.4對(duì)象的撤消——析構(gòu)函數(shù) 3.3.5*對(duì)象的深入理解 48第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.3.1 對(duì)象的聲明 inti;//聲明一個(gè)整型對(duì)象i,該對(duì)象占有32個(gè)字節(jié)的空間charch;//聲明一個(gè)字符對(duì)象ch,該對(duì)象占有1個(gè)字節(jié)的空間CTimeMyTime;//聲明一個(gè)日期時(shí)間對(duì)象MyTimeCPointMyPoint;////聲明個(gè)點(diǎn)對(duì)象MyPointCRectMyRect;//聲明一個(gè)矩形對(duì)象MyRecct其中CTime、CPoint、CRect是VC中MFC類庫中的一些通用類,這些類在實(shí)際設(shè)計(jì)程序時(shí)有著很重要的作用。49第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.3.2 對(duì)象的使用
當(dāng)聲明了對(duì)象后,就可以使用該對(duì)象所隸屬的類的公有(在public部分定義的)成員變量和成員函數(shù)。
對(duì)象的使用,關(guān)鍵是使用對(duì)象所屬類的成員函數(shù),即熟悉該類都有哪些常用的成員函數(shù)。
50第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-15】建立一個(gè)日期類,并且主函數(shù)中使用其公有的成員函。主文件為DefObject.cpp
#include<iostream.h>classTDate{public: voidSetDate(intyear,intmonth,intday) { m_year=year; m_month=month; m_day=day; }voidShowDate() { cout<<"Thedateis"<<m_year<<"-"<<m_month<<"-"<<m_day<<endl; }private: intm_year; intm_month; intm_day;};51第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidmain(){
TDateToday;//建立一個(gè)日期對(duì)象
Today.SetDate(2004,8,1);//調(diào)用設(shè)置日期的函數(shù)
Today.ShowDate();//調(diào)用顯示日期的函數(shù)}程序運(yùn)行結(jié)果為:Thedateis2004-8-152第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.3.3 對(duì)象的初始化——
構(gòu)造函數(shù)
構(gòu)造函數(shù)是系統(tǒng)在創(chuàng)建對(duì)象時(shí)進(jìn)行初始化的工具構(gòu)造函數(shù)是類的一種特殊的成員函數(shù)
其特殊性在于:
(1)功能特殊:構(gòu)造函數(shù)是為新創(chuàng)建的對(duì)象分配內(nèi)存空間或?yàn)閿?shù)據(jù)成員賦初值,一般在創(chuàng)建對(duì)象時(shí),為對(duì)象做初始化的工作。
(2)形式特殊:構(gòu)造函數(shù)的名稱和類的名字相同,并且該函數(shù)無函數(shù)類型的說明;
(3)調(diào)用時(shí)機(jī)特殊:構(gòu)造函數(shù)不像普通成員函數(shù)那樣需要顯式調(diào)用(對(duì)象.成員函數(shù)的形式或?qū)ο笾羔?>成員函數(shù)),它是隱式調(diào)用,即在一個(gè)新對(duì)象建立時(shí)(包含兩種情況:一種是在對(duì)象的聲明語句中,另一種是用new函數(shù)建立新的動(dòng)態(tài)對(duì)象時(shí)),該對(duì)象所隸屬類的構(gòu)造函數(shù)自動(dòng)被調(diào)用。
53第3章:VC程序設(shè)計(jì)核心-類與對(duì)象注:當(dāng)類中不給出類的構(gòu)造函數(shù)時(shí),系統(tǒng)將自動(dòng)給出默認(rèn)的構(gòu)造函數(shù),這個(gè)構(gòu)造函數(shù)沒有參數(shù),而且函數(shù)體為空
構(gòu)造函數(shù)不允許有返回值,也不許定義函數(shù)的返回值類型
構(gòu)造函數(shù)可以重載,即可以定義多個(gè)參數(shù)個(gè)數(shù)不同或類型不同的構(gòu)造函數(shù)。54第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.3.4 對(duì)象的撤消——
析構(gòu)函數(shù)
析構(gòu)函數(shù)是在撤消對(duì)象時(shí)進(jìn)行收尾工作的工具。它的功能是:在對(duì)象被撤消時(shí),對(duì)該對(duì)象所占的空間進(jìn)行釋放。當(dāng)類中沒有給出析構(gòu)函數(shù)時(shí),系統(tǒng)將自動(dòng)生成一個(gè)缺省的構(gòu)造函數(shù)。
當(dāng)撤消對(duì)象時(shí)(對(duì)象的生存期結(jié)束或通過delete函數(shù)釋放動(dòng)態(tài)對(duì)象),系統(tǒng)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)。析構(gòu)函數(shù)不允許定義函數(shù)的返回值類型,定義析構(gòu)函數(shù)時(shí)不能指定任何形式的參數(shù),而且析構(gòu)函數(shù)也不能重載,即析構(gòu)函數(shù)在一個(gè)類中只能有一個(gè)。55第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-16】一個(gè)包含構(gòu)造函數(shù)和析構(gòu)函數(shù)的例子。程序的主文件為ConstructorExam.cpp。
#include<iostream.h>#include<iomanip.h>classExl{private: intx;public: Exl(){cout<<"Ex1類的對(duì)象建立,其構(gòu)造函數(shù)被調(diào)用\n";} ~Exl(){cout<<"Ex1類的對(duì)象撤消,其析構(gòu)函數(shù)被調(diào)用\n";} voidsetdata(inti){x=i*2;}//在類中定義成員函數(shù)setdata() voidprint();};//類Exl定義結(jié)束56第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classEx2{ inty;public: Ex2(){cout<<"Ex2類的對(duì)象建立,其構(gòu)造函數(shù)被調(diào)用\n";} ~Ex2(){cout<<"Ex2類的對(duì)象撤消,其析構(gòu)函數(shù)被調(diào)用\n";} voidsetdata(intj){y=j*j;} voidprint();};//類Ex2定義結(jié)束voidEx2::print(){ cout<<"classEx2:"<<setw(6)<<y<<"\n";}//成員函數(shù)print()定義結(jié)束57第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidmain(){ Exls; Ex2t; s.setdata(5); s.print(); t.setdata(5); t.print();}程序運(yùn)行結(jié)果為:Ex1類的對(duì)象建立,其構(gòu)造函數(shù)被調(diào)用Ex2類的對(duì)象建立,其構(gòu)造函數(shù)被調(diào)用classExl:10classEx2:25Ex2類的對(duì)象撤消,其析構(gòu)函數(shù)被調(diào)用Ex1類的對(duì)象撤消,其析構(gòu)函數(shù)被調(diào)用58第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.3.5*對(duì)象的深入理解 1.對(duì)象就是變量
2.對(duì)象是封裝了屬性和行為的基本單位 3.對(duì)象是一個(gè)有限狀態(tài)自動(dòng)機(jī)
59第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.4類的繼承與派生 3.4.1類與類之間的四種關(guān)系 3.4.2繼承的概念 3.4.3派生類的聲明 3.4.4基類成員的訪問控制 3.4.5派生與繼承的應(yīng)用
60第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.4.1類與類之間的四種關(guān)系
是封裝了事物屬性和方法的同類對(duì)象的集合。
類UML(unifiedmodellanguage,統(tǒng)一建模語言)認(rèn)為,類之間主要存在四種關(guān)系。1.關(guān)聯(lián)(Association)關(guān)系
關(guān)聯(lián)關(guān)系表示兩個(gè)類之間存在某種語義上的聯(lián)系,即與該關(guān)聯(lián)連接的類的對(duì)象之間具有一定的語義連接關(guān)系,該關(guān)系表達(dá)了類之間的一種相關(guān)性。61第3章:VC程序設(shè)計(jì)核心-類與對(duì)象2.依賴(Dependency)關(guān)系
依賴關(guān)系描述的是兩個(gè)類之間的語義上的連接關(guān)系,它是一種“Use-A”關(guān)系。假設(shè)有兩個(gè)元素A與B,如果修改元素A的定義可能會(huì)引起對(duì)另一個(gè)元素B的定義的修改,則稱元素B依賴于A。
3.聚合(Aggregation)關(guān)系聚合關(guān)系是一種“Has-A”關(guān)系,它體現(xiàn)的是類之間的一種整體與部分的關(guān)系。例如汽車包括四個(gè)輪子和一個(gè)發(fā)動(dòng)機(jī)等。62第3章:VC程序設(shè)計(jì)核心-類與對(duì)象4.泛化(Generalization)關(guān)系泛化關(guān)系是一種“Is-A”關(guān)系,它描述的是類之間的“一般”與“特殊”的關(guān)系。具有共同特性的元素可以抽象為一般類,并通過增加其內(nèi)涵,進(jìn)一步抽象成特殊類。該關(guān)系可以將類組成一種有層次、有分類的結(jié)構(gòu)。例如:狗是一種哺乳動(dòng)物,哺乳動(dòng)物是一種動(dòng)物等。在VC中建立類之間的泛化關(guān)系采用的是繼承機(jī)制。63第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.4.2繼承的概念 繼承是描述類與類之間關(guān)系的一個(gè)概念,它提高了代碼的重用性,使得程序更加模塊化,便于程序更簡(jiǎn)單而又準(zhǔn)確地描述事物。
繼承關(guān)系可以用由派生類指向基類的箭頭表示,如圖3.4所示:
交通工具飛機(jī)汽車火車轎車卡車面包車64第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.4.3派生類的聲明單繼承中派生類的聲明格式為:
class派生類類名:訪問控制限定符基類名;其中訪問控制限定符號(hào)可以是public(公有派生)、protected(保護(hù)派生)和private(私有派生)?!纠?-17】一個(gè)派生類的聲明實(shí)例。如果交通工具用前面講的類TVehicle來抽象表示,汽車用類TCar來抽象表示的話,那么汽車從交通工具繼承而來(或交通工具派生汽車的)的語義表示成C++語言的語法描述為:65第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classTCar:publicTVehicle{public:voidInitialize(intwheels,floatweight,intpassenger=4);GetPassenger(void);private:intm_passenger;};66第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.4.4基類成員的訪問控制
派生類對(duì)基類成員的訪問不僅取決于基類成員聲明的訪問控屬性,還取決于派生類對(duì)基類的“繼承程度”。繼承程度有有三種:公有(public)、受保護(hù)(protected)和私有(private)類型的繼承。
我們可以根據(jù)下表中的繼承成員訪問控制規(guī)則來決定使用哪種訪問方式更合理,不同的訪問控制,決定了基類可以被派生類所訪問的“開放”程度。
67第3章:VC程序設(shè)計(jì)核心-類與對(duì)象表3.1繼承成員訪問控制規(guī)則繼承訪問控制基類成員訪問控制在派生類中的訪問控制
publicpublicpublicprotectedprotectedprivate不可訪問
protectedpublicprotectedprotectedprotectedprivate不可訪問
privatepublicprivateprotectedprivateprivate不可訪問68第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-19】一個(gè)使用類的繼承實(shí)例。主文件為InheritTest.cpp。3.4.5派生與繼承的應(yīng)用#include"iostream.h"classTVehicle//交通工具類的聲明{public: voidInitialize(intwheels,floatweight); intGetWheels(void){returnm_wheels;} floatGetWeight(void){returnm_weight;}private: intm_wheels;//輪子
floatm_weight;//載重};69第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidTVehicle::Initialize(intwheels,floatweight){ m_wheels=wheels;m_weight=weight;}classTCar:publicTVehicle//汽車類從交通工具類公有派生{public: voidInitialize(intwheels,floatweight,intpassenger); intGetPassenger(void){returnm_passenger;}private: intm_passenger;//乘客數(shù)};voidTCar::Initialize(intwheels,floatweight,intpassenger=4){ TVehicle::Initialize(wheels,weight);//調(diào)用父類的函數(shù)進(jìn)行初始化}70第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidmain(){ TVehicleVehicleInstance;//聲明一個(gè)交通工具對(duì)象VehicleInstance TCarCarInstance;//聲明一個(gè)汽車對(duì)象CarInstance VehicleInstance.Initialize(4,6);//初始化交通工具
cout<<"交通工具輪子的個(gè)數(shù)是:"<<VehicleInstance.GetWheels()<<endl; cout<<"交通工具輪子的載重為:"<<VehicleInstance.GetWeight()<<endl; CarInstance.Initialize(1,2);//初始化汽車 //調(diào)用從基類繼承而來的函數(shù)GetWheels等
cout<<"汽車的輪子、載重和乘客數(shù)為:
m_passenger=passenger;"<<CarInstance.GetWheels()<<"\t"<<CarInstance.GetWeight()<<"\t"; cout<<CarInstance.GetPassenger()<<endl;//調(diào)用派生類新增的函數(shù)GetPassenger}71第3章:VC程序設(shè)計(jì)核心-類與對(duì)象程序運(yùn)行結(jié)果為:交通工具輪子的個(gè)數(shù)是:4交通工具輪子的載重為:6汽車的輪子、載重和乘客數(shù)為:12472第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.5 類的多態(tài)性 3.5.1多態(tài)性概述 3.5.2多態(tài)性的類型 3.5.3編譯時(shí)多態(tài)性的兩種方式 3.5.4運(yùn)行時(shí)多態(tài)性的實(shí)現(xiàn)條件 3.5.5純虛函數(shù)與抽象類 3.5.6*使用虛函數(shù)的好處 習(xí)題73第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.5.1多態(tài)性概述
在VC中,這種同一符號(hào)或名字在不同情況下表現(xiàn)為不同的語義現(xiàn)象稱為多態(tài)性。
嚴(yán)格地講,在VC中,不同的類可以有語義相同的函數(shù),這些函數(shù)在概念上是相似的,但對(duì)應(yīng)各自的類來說,其實(shí)現(xiàn)是不同的,因而對(duì)象在接收到同樣的函數(shù)調(diào)用時(shí)所引發(fā)的行為有可能是不同的,這一功能稱為多態(tài)性。直觀地講就是“一個(gè)名稱,多個(gè)函數(shù)”。74第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.5.2多態(tài)性的類型
程序設(shè)計(jì)的多態(tài)性有兩種形式:編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。
多態(tài)性的實(shí)現(xiàn)與聯(lián)編有關(guān)。將一個(gè)函數(shù)的調(diào)用與其相應(yīng)的函數(shù)體代碼相鏈接的過程,稱為函數(shù)聯(lián)編。C++中有兩種類型的聯(lián)編:靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編。75第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
靜態(tài)聯(lián)編是指在調(diào)用同名函數(shù)(即重載函數(shù))時(shí),編譯器將根據(jù)調(diào)用時(shí)所使用的實(shí)際參數(shù)個(gè)數(shù)、類型的不同確定應(yīng)該調(diào)用哪一個(gè)函數(shù)的實(shí)現(xiàn),它是在程序編譯階段就確定下來的多態(tài)性。靜態(tài)聯(lián)編通過使用重載(overload)機(jī)制來獲得,重載機(jī)制包括函數(shù)重載和運(yùn)算符重載。
動(dòng)態(tài)聯(lián)編是在程序的運(yùn)行階段根據(jù)當(dāng)時(shí)的情況來確定應(yīng)該調(diào)用哪個(gè)同名函數(shù)的實(shí)現(xiàn)。動(dòng)態(tài)聯(lián)編主要通過繼承與虛函數(shù)兩者結(jié)合來實(shí)現(xiàn)的。
76第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
靜態(tài)聯(lián)編的代碼鏈接工作是在編譯時(shí)完成的,所以運(yùn)行時(shí)不需要額外時(shí)間來做這些工作,因此靜態(tài)聯(lián)編的代碼效率較高。
動(dòng)態(tài)聯(lián)編將函數(shù)調(diào)用的鏈接時(shí)間后移到代碼執(zhí)行的時(shí)候,這必然使函數(shù)調(diào)用時(shí)間開銷增加,效率降低,但大大增強(qiáng)了語言的靈活性。程序員可以根據(jù)實(shí)際情況需要來決定使用哪一種聯(lián)編方式,從而兼顧代碼的高效性和靈活性。
靜態(tài)聯(lián)編與動(dòng)態(tài)聯(lián)編各有優(yōu)缺點(diǎn):77第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.5.3編譯時(shí)多態(tài)性的兩種
形式----函數(shù)與運(yùn)算符重載1.函數(shù)重載
兩個(gè)以上的函數(shù),取相同的函數(shù)名稱,但是形參個(gè)數(shù)或者類型不同,編譯器根據(jù)實(shí)參和形參的類型和個(gè)數(shù)選擇最匹配的函數(shù),來自動(dòng)地確定調(diào)用哪一個(gè)函數(shù),這就是函數(shù)的重載。函數(shù)重載包括普通成員函數(shù)重載和類的成員函數(shù)重載
,下面給出相應(yīng)的實(shí)例。
【例3-20】普通函數(shù)重載的例子。給函數(shù)add()定義多個(gè)函數(shù)來實(shí)現(xiàn),該函數(shù)的功能是求和,可以求兩個(gè)整型數(shù)之和,兩個(gè)浮點(diǎn)數(shù)之和,也可以求三個(gè)雙精度浮點(diǎn)數(shù)之和,每種實(shí)現(xiàn)對(duì)應(yīng)著一個(gè)函數(shù)體,這些函數(shù)的名字相同,但是函數(shù)的參數(shù)個(gè)數(shù)或類型不同,這就是函數(shù)重載。在VC+中,函數(shù)可以共享同一個(gè)名字,只是這些同名函數(shù)的參數(shù)表有所不同。程序的主文件為Function.cpp。78第3章:VC程序設(shè)計(jì)核心-類與對(duì)象#include<iostream.h>intadd(inta,intb){ returna+b;}floatadd(floatx,floaty){ returnx+y;}voidadd(doublea,doubleb,doublec){ cout<<a+b+c<<endl;}voidmain(){intm=1,n=2;floatx=1.2,y=2.3;doublea=2.0,b=3.0,c=2.5;cout<<add(m,n)<<endl;//因?yàn)閙與n為int型,故調(diào)用的是第一個(gè)add函數(shù)
cout<<add(x,y)<<endl;//因?yàn)閤與y為float型,故調(diào)用的是第二個(gè)add函數(shù)
add(a,b,c);//因?yàn)閍、b、c為double,且包含三個(gè)參數(shù)型,故調(diào)用的是第三個(gè)add函數(shù)}79第3章:VC程序設(shè)計(jì)核心-類與對(duì)象從程序的運(yùn)行結(jié)果來看add(m,n)是調(diào)用了intadd(inta,intb)函數(shù);add(x,y)調(diào)用了函數(shù)floatadd(floatx,floaty);add(a,b,c)調(diào)用了voidadd(doublea,doubleb,doublec)函數(shù)。這些函數(shù)可以同名,同名的函數(shù)為重載函數(shù)。程序的運(yùn)行結(jié)果是:33.57.580第3章:VC程序設(shè)計(jì)核心-類與對(duì)象注意:(1)函數(shù)重載時(shí),函數(shù)聲明必須能互相區(qū)別,即函數(shù)參數(shù)個(gè)數(shù)或參數(shù)類型必須有所不同,如果只有函數(shù)的返回值不同,不能區(qū)分重載函數(shù);(2)函數(shù)功能一般相類似,本質(zhì)上有區(qū)別的函數(shù),最好不要重載;(3)不同參數(shù)傳遞方式無法區(qū)別重載函數(shù)。例如:intadd(inta,intb);intadd(int&a,int&b);這兩個(gè)函數(shù)不能作為重載函數(shù),編譯時(shí)會(huì)出錯(cuò)。
81第3章:VC程序設(shè)計(jì)核心-類與對(duì)象【例3-21】類的成員函數(shù)重載的例子。
類的成員函數(shù)重載的最典型的情況在類的構(gòu)造函數(shù)的重載。MFC類庫中有一個(gè)點(diǎn)類CPoint,查看MSDN的說明,知道它有多個(gè)構(gòu)造函數(shù),下面為其中的構(gòu)造函數(shù)的原型說明:CPoint(intinitX,intinitY);CPoint(POINTinitPt);CPoint(SIZEinitSize);82第3章:VC程序設(shè)計(jì)核心-類與對(duì)象2.運(yùn)算符重載
運(yùn)算符重載本質(zhì)上就是函數(shù)的重載,是函數(shù)重載的特殊形式(函數(shù)名為運(yùn)算符號(hào)),VC語言中允許程序員重新定義運(yùn)算符的語義,這一機(jī)制稱為運(yùn)算符重載。與函數(shù)重載類似,運(yùn)算符重載就是當(dāng)運(yùn)算符的操作對(duì)象不同時(shí),運(yùn)算符呈現(xiàn)出不同的運(yùn)算狀態(tài)。運(yùn)算符函數(shù)有兩種形式:一種是在類中定義的運(yùn)算符成員函數(shù),即類成員運(yùn)算符;另一種是在類之外定義的運(yùn)算符函數(shù),通常使用友元形式,即友元運(yùn)算符。83第3章:VC程序設(shè)計(jì)核心-類與對(duì)象類的運(yùn)算符重載的定義形式類型類名::operator重載運(yùn)算符(參數(shù)表){……//運(yùn)算符函數(shù)體}【例3-22】用類的成員函數(shù)重載運(yùn)算符“+”實(shí)現(xiàn)復(fù)數(shù)相加的例子,重載運(yùn)算符“==”實(shí)現(xiàn)兩個(gè)復(fù)數(shù)是否相等的判斷。程序的主文件為Operator.cpp84第3章:VC程序設(shè)計(jì)核心-類與對(duì)象#include"iostream.h"classTComplex//定義數(shù)學(xué)上的復(fù)數(shù)類{ public: TComplex(floatreal=0,floatimage=0);//缺省構(gòu)造函數(shù)
TComplex(constTComplex&other);//拷貝構(gòu)造函數(shù)
TComplexoperator+(constTComplex&other);//加法運(yùn)算符重載
booloperator==(constTComplex&other)//判斷兩個(gè)復(fù)數(shù)是否相等的內(nèi)聯(lián)函數(shù)實(shí)現(xiàn) {return((m_real==other.m_real)&&(m_image==other.m_image)); }; voidShowValue();//顯示復(fù)數(shù)值private: floatm_real;//復(fù)數(shù)的實(shí)部
floatm_image;//復(fù)數(shù)的虛部};85第3章:VC程序設(shè)計(jì)核心-類與對(duì)象TComplex::TComplex(floatreal,floatimage)//缺省的構(gòu)造函數(shù)的實(shí)現(xiàn){
m_real=real; m_image=image;}TComplex::TComplex(constTComplex&other)//拷貝構(gòu)造函數(shù)的實(shí)現(xiàn){
m_real=other.m_real; m_image=other.m_image;}TComplexTComplex::operator+(constTComplex&other)//加法運(yùn)算符重載的實(shí)現(xiàn)代碼{
TComplextemp; temp.m_real=m_real+other.m_real; temp.m_image=m_image+other.m_image; returntemp;}86第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidTComplex::ShowValue()//顯示復(fù)數(shù)值代碼{cout<<m_real;//輸出實(shí)部if(m_image>0) cout<<"+"<<m_image<<"i";if(m_image<0) cout<<m_image<<"i";cout<<endl;}voidmain(){ TComplexComplex1(6,8);//將復(fù)數(shù)Complex1設(shè)置為4+5i TComplexComplex2(-2,-3);//將復(fù)數(shù)Complex1設(shè)置為-2-3i,調(diào)用缺省構(gòu)造函數(shù)完成
TComplexComplex3(Complex1);//用Complex1初始化Complex3,調(diào)用拷貝構(gòu)造函數(shù)完成后,這兩個(gè)復(fù)數(shù)相等
TComplexComplex4,Complex5;//將復(fù)數(shù)Complex4,Complex5設(shè)置為0,調(diào)用缺省構(gòu)造函數(shù)完成87第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
Complex1.ShowValue();//顯示復(fù)數(shù)complex1 Complex2.ShowValue(); Complex3.ShowValue(); Complex4.ShowValue(); Complex5.ShowValue(); Complex4=Complex1+Complex2;//以運(yùn)算符形式調(diào)用復(fù)數(shù)的相加,和兩個(gè)數(shù)的普通加法形式一樣
Complex4.ShowValue(); Complex5=Complex1.operator+(Complex2);//以函數(shù)形式調(diào)用復(fù)數(shù)的相加,注意在運(yùn)算符的前面必須加上關(guān)鍵字operator Complex5.ShowValue(); if(Complex4==Complex5)//利用重載的運(yùn)算符==判斷兩個(gè)復(fù)數(shù)是否相等
cout<<"Complex4和Complex5相等\n"; else cout<<"Complex4和Complex5不相等\n";}88第3章:VC程序設(shè)計(jì)核心-類與對(duì)象程序運(yùn)行結(jié)果:6+8i-2-3i6+8i004+5i4+5iComplex4和Complex5相等
運(yùn)算符重載增加了程序的靈活性,但運(yùn)算符重載不能改變運(yùn)算符的基本功能,也不能改變運(yùn)算符的優(yōu)先級(jí)和結(jié)合性,運(yùn)算符重載不能使用缺省參數(shù)。89第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.5.4運(yùn)行時(shí)多態(tài)性
的實(shí)現(xiàn)條件 1.定義超載(overriding)函數(shù)要使程序出現(xiàn)運(yùn)行時(shí)的多態(tài)性,必須有繼承關(guān)系。在類的層次結(jié)構(gòu)中,定義完全相同的函數(shù)原型,但這些類層次中同名函數(shù)的實(shí)現(xiàn)代碼卻不同。這些不僅同名而且同原型的函數(shù)稱作函數(shù)的超載(override)。
2.聲明超載函數(shù)為虛函數(shù)
1、聲明虛擬函數(shù)
classTAnimal{private:
charm_strName[10];public:virtualvoidRoar(){cout<<"并不知道哪個(gè)類的動(dòng)物在叫"<<endl;}//此函數(shù)說明為虛函數(shù)};2、使用繼承
90第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.通過基類指針來訪問
一般情況下,指向一種類型對(duì)象的指針不允許指向另一種類型的對(duì)象。但指向基類的指針可以指向派生類對(duì)象【例3-23】虛函數(shù)和多態(tài)性的應(yīng)用實(shí)例。程序中定義了鳥類、狗類和老虎類,我們知道,不論是鳥、狗還是老虎,他們都會(huì)叫,但它們的叫聲是完全不同的。如果這三個(gè)類都有一個(gè)叫Roar()的成員函數(shù),那么在這三個(gè)類的Roar函數(shù)的實(shí)現(xiàn)代碼肯定是不一樣的。在TAnimal類的Roar函數(shù)之前加上Virtual,使其成為虛函數(shù),然后再通過指向基類TAnimal的指針來訪問,就可實(shí)現(xiàn)運(yùn)行時(shí)的多態(tài)性。程序的主文件為DynaPoly.cpp。91第3章:VC程序設(shè)計(jì)核心-類與對(duì)象#include<iostream.h>#include<conio.h>#include<string.h>classTAnimal{private: charm_strName[10];public: virtualvoidRoar() {cout<<"并不知道哪個(gè)類的動(dòng)物在叫"<<endl;} voidSetName(char*strName) {strcpy(m_strName,strName); } char*GetName() { returnm_strName; }};classTBird:publicTAnimal//定義鳥類TBird{public: TBird(){SetName("Bird");} voidRoar() {cout<<"The"<<GetName()<<"isRoaring…isitagoodsinger?\n"; }};92第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classTDog:publicTAnimal//定義狗類TDog{public: TDog(){SetName("Dog");} voidRoar() {cout<<"The"<<GetName()<<"isRoaring…isitboring?\n"; }};
classTTiger:publicTAnimal//定義老虎類TTiger{public: TTiger(){SetName("Tiger");} voidRoar(){ cout<<"The"<<GetName()<<“isRoaring…isitfrightful?\n"; }};93第3章:VC程序設(shè)計(jì)核心-類與對(duì)象voidmain(){ TAnimalanimal; TBirdbird; TDogdog; TTigertiger;cout<<"以下為靜態(tài)聯(lián)編--------------------------\n"; //通過對(duì)象的方式來訪問是靜態(tài)聯(lián)編
animal.Roar(); bird.Roar(); dog.Roar(); tiger.Roar(); cout<<"以下為動(dòng)態(tài)聯(lián)編--------------------------\n";/*通過指針的方式來訪問虛擬函數(shù)是動(dòng)態(tài)聯(lián)編,倘若把派生類的Roar函數(shù)前的Virtual去掉,則變?yōu)殪o態(tài)聯(lián)編*/
TAnimal*pAnimal; pAnimal=&bird; pAnimal->Roar(); pAnimal=&dog; pAnimal->Roar(); pAnimal=&tiger; pAnimal->Roar();}94第3章:VC程序設(shè)計(jì)核心-類與對(duì)象程序運(yùn)行結(jié)果為:
以下為靜態(tài)聯(lián)編--------------------------并不知道哪個(gè)類的動(dòng)物在叫TheBirdisRoaring...isitagoodsinger?TheDogisRoaring...isitboring?TheTigerisRoaring...isitfrightful?
以下為動(dòng)態(tài)聯(lián)編--------------------------TheBirdisRoaring...isitagoodsinger?TheDogisRoaring...isitboring?TheTigerisRoaring...isitfrightful?95第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
通過指針的方式來訪問虛函數(shù)是動(dòng)態(tài)聯(lián)編,倘若把派生類的Roar函數(shù)前的virtual去掉,則變?yōu)殪o態(tài)聯(lián)編。自己把去掉virtual的程序運(yùn)行一下,其運(yùn)行結(jié)果為:以下為靜態(tài)聯(lián)編--------------------------并不知道哪個(gè)類的動(dòng)物在叫TheBirdisRoaring...isitagoodsinger?TheDogisRoaring...isitboring?TheTigerisRoaring...isitfrightful?96第3章:VC程序設(shè)計(jì)核心-類與對(duì)象以下為動(dòng)態(tài)聯(lián)編--------------------------并不知道哪個(gè)類的動(dòng)物在叫并不知道哪個(gè)類的動(dòng)物在叫并不知道哪個(gè)類的動(dòng)物在叫可見要實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編,必須將基類的Roar定義成為虛函數(shù),這種情形稱為函數(shù)的超載(Override)或同名覆蓋97第3章:VC程序設(shè)計(jì)核心-類與對(duì)象3.5.5純虛函數(shù)與抽象類純虛函數(shù)的定義
在基類中只聲明虛函數(shù)而不給出具體的定義,將它的具體定義放在各派生類中,稱此虛函數(shù)為純虛函數(shù)(purevirtualfunction)。
聲明了純虛函數(shù)的類,稱為抽象類(abstractclass)。純虛擬函數(shù)的聲明形式如下:virtual函數(shù)類型函數(shù)原型(參數(shù)表)=0;將虛擬函數(shù)的原型設(shè)置為0,該虛函數(shù)即為純虛函數(shù)。98第3章:VC程序設(shè)計(jì)核心-類與對(duì)象(2)抽象類的定義
只能用作別的類的基類,而本身不能直接創(chuàng)建對(duì)象的類稱為抽象基類。帶有純虛函數(shù)的基類是抽象類。抽象類派生一個(gè)新類后,可以對(duì)虛函數(shù)添加實(shí)現(xiàn)代碼,此時(shí),該類就不再是抽象類;反之仍然為抽象類。(3)抽象類的使用【例3-24】純虛函數(shù)的例子。下面的程序用于計(jì)算三角形和矩形的面積,設(shè)計(jì)一個(gè)抽象類shape,它表示具有形狀的東西,體現(xiàn)了抽象的概念,在它下面可以派生出多種具體形狀,比如三角形、矩形、橢圓等。為了計(jì)算這些圖形的面積,只需在類shape中聲明一純虛函數(shù)area(),而將計(jì)算具體形狀面積的定義放到其派生類中。程序的主文件為VirtualFunc.cpp。99第3章:VC程序設(shè)計(jì)核心-類與對(duì)象
#include<iostream.h>classshape{protected:doublex,y;public:voidset(doublei,doubej){x=i;y=j;}virtualvoidarea()=0;//聲明純虛函數(shù)};//抽象類shapt定義結(jié)束classtriangle:publicshape{public:voidarea(){cout<<”TriangleS=1/2*”<<x<<”*”<<y<<”=”<<0.5*x*y<<”\n”;}//派生類重新定義虛擬函數(shù)};100第3章:VC程序設(shè)計(jì)核心-類與對(duì)象classrectangle:publicshape{public:voidarea(){cout<<”RectangleS=”<<x<<”*”<<y<<”=”<<x*y<<”\n”;}//派生類重新定義虛擬函數(shù)};//派生類rectangle定義結(jié)束voidmain(){shape*p;trianglet;rectangler;p=&t;p->set(5.1,10);p->area();p=&r;p->set(5.1,10);p->
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 人教版九年級(jí)歷史與社會(huì)上冊(cè)教學(xué)設(shè)計(jì)3.1.2全面侵華戰(zhàn)爭(zhēng)的爆發(fā)
- 2025年中國(guó)高純碘甲烷行業(yè)市場(chǎng)分析及投資價(jià)值評(píng)估前景預(yù)測(cè)報(bào)告
- 2025年中國(guó)呋喃酮甲醚行業(yè)市場(chǎng)分析及投資價(jià)值評(píng)估前景預(yù)測(cè)報(bào)告
- 二年級(jí)下冊(cè)道德與法治教學(xué)設(shè)計(jì)-3你好 四季 第1課時(shí) 粵教版
- 愛育心以愛護(hù)航主題班會(huì)說課稿
- 第二十四課 學(xué)會(huì)自我保護(hù)《我的身體會(huì)說話》教學(xué)設(shè)計(jì)-心理健康五年級(jí)下冊(cè)北師大版
- 第二十五章 概率初步 小結(jié) 說課稿 人教版九年級(jí)數(shù)學(xué)上冊(cè)
- 九年級(jí)英語下冊(cè) Module 2 Environmental problems Unit 4 Natural disasters說課稿5 牛津深圳版
- 保利水管知識(shí)培訓(xùn)課件
- 中學(xué)心育課說課稿:網(wǎng)絡(luò)那頭的他(她)
- 設(shè)備編號(hào)管理標(biāo)準(zhǔn)與實(shí)施細(xì)則
- 變電站安全準(zhǔn)入培訓(xùn)內(nèi)容課件
- 2025年中醫(yī)館轉(zhuǎn)讓協(xié)議書
- 學(xué)堂在線 走進(jìn)心理學(xué) 章節(jié)測(cè)試答案
- 國(guó)外設(shè)計(jì)管理辦法
- 2025年湖南食品藥品職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)試題及答案解析
- 幼兒園中國(guó)速度主題課件
- 學(xué)堂在線 極區(qū)航海導(dǎo)航保障 期末考試答案
- 初中誠(chéng)實(shí)守信說課課件
- 2025年全國(guó)統(tǒng)一高考英語Ⅰ卷(含解析)
- 小兒過敏性紫癜護(hù)理常規(guī)
評(píng)論
0/150
提交評(píng)論