第2章 面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)_第1頁(yè)
第2章 面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)_第2頁(yè)
第2章 面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)_第3頁(yè)
第2章 面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)_第4頁(yè)
第2章 面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)_第5頁(yè)
已閱讀5頁(yè),還剩70頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

VisualC++實(shí)用教程第2章面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)1教學(xué)目標(biāo):了解面向?qū)ο蟮幕靖拍?/p>

熟練掌握類(lèi)、對(duì)象、派生類(lèi)的定義和使用

掌握類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)的定義和特點(diǎn)

能夠利用虛函數(shù)實(shí)現(xiàn)多態(tài)性熟悉友元的特性

2教學(xué)內(nèi)容:2.1面向?qū)ο蟮幕靖拍?.2類(lèi)和對(duì)象的定義2.3繼承性和派生類(lèi)2.4多態(tài)性2.5友元2.6模板32.1

面向?qū)ο蟮幕靖拍钣^點(diǎn):自然界是由實(shí)體(對(duì)象)所組成。程序設(shè)計(jì)方法:使用面向?qū)ο蟮挠^點(diǎn)來(lái)描述、模仿并處理現(xiàn)實(shí)問(wèn)題。要求:高度概括、分類(lèi)、和抽象。目的:實(shí)現(xiàn)軟件設(shè)計(jì)的產(chǎn)業(yè)化。程序=多個(gè)對(duì)象+消息4類(lèi)和對(duì)象對(duì)象是現(xiàn)實(shí)世界中一個(gè)實(shí)際存在的事物對(duì)象的靜態(tài)特征對(duì)象的行為類(lèi)是具有相同屬性和行為的一組對(duì)象的集合,它為屬于該類(lèi)的全部對(duì)象提供了統(tǒng)一的抽象描述,其內(nèi)部包括屬性和行為兩個(gè)主要部分。對(duì)象之間的交互:發(fā)送消息5封裝封裝的目的是隱藏對(duì)象的內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)。通過(guò)封裝,可以將對(duì)象的外部接口與內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)分開(kāi)。

目的是增強(qiáng)安全性和簡(jiǎn)化編程,使用者不必了解具體的實(shí)現(xiàn)細(xì)節(jié),而只需要通過(guò)外部接口,以特定的訪(fǎng)問(wèn)權(quán)限,來(lái)使用類(lèi)的成員。6繼承繼承是C++中支持層次分類(lèi)的一種機(jī)制,允許程序員在保持原有類(lèi)特性的基礎(chǔ)上,對(duì)新類(lèi)進(jìn)行更具體的說(shuō)明。實(shí)現(xiàn):聲明派生類(lèi)——2.37多態(tài)性多態(tài):同一名稱(chēng),不同的功能實(shí)現(xiàn)方式。目的:標(biāo)識(shí)統(tǒng)一,減少程序中標(biāo)識(shí)符的個(gè)數(shù);接口統(tǒng)一,增加程序的靈活性實(shí)現(xiàn):——2.4編譯時(shí)的多態(tài)性:重載函數(shù)運(yùn)行時(shí)的多態(tài)性:虛函數(shù)82.2類(lèi)與對(duì)象的定義類(lèi)是C++的靈魂,如果不真正掌握類(lèi),就不能真正掌握C++C++中的類(lèi)就是一種用戶(hù)自己定義的數(shù)據(jù)類(lèi)型,和其它數(shù)據(jù)類(lèi)型不同的是,組成這種類(lèi)型的不僅可以有數(shù)據(jù),而且可以有對(duì)數(shù)據(jù)進(jìn)行操作的函數(shù)。為了封裝的需要,一般將類(lèi)的定義放在一個(gè).h文件中,而將類(lèi)的成員函數(shù)的實(shí)現(xiàn)放在一個(gè).cpp文件中。92.2.1類(lèi)的定義class類(lèi)名稱(chēng){

public:

公有成員(外部接口)

private:

私有成員

protected:

保護(hù)成員};類(lèi)與外部的接口只允許本類(lèi)中的函數(shù)訪(fǎng)問(wèn)(可省略)只能由本類(lèi)及其派生類(lèi)的成員函數(shù)訪(fǎng)問(wèn)是必需的成員訪(fǎng)問(wèn)說(shuō)明符10例2.1:圓類(lèi)的定義見(jiàn)教材24頁(yè)11類(lèi)的數(shù)據(jù)成員(成員變量):與一般的變量聲明相同,但需要將它放在類(lèi)的聲明體中,一般為私有訪(fǎng)問(wèn)屬性。類(lèi)的成員函數(shù)定義:在類(lèi)中說(shuō)明原型,類(lèi)外給出函數(shù)體實(shí)現(xiàn),函數(shù)名之前必須加類(lèi)名和作用域區(qū)分符限定將成員函數(shù)定義為內(nèi)聯(lián)函數(shù):成員函數(shù)在類(lèi)的內(nèi)部定義,此時(shí)無(wú)須使用inline關(guān)鍵字,成員函數(shù)自動(dòng)為內(nèi)聯(lián)函數(shù)。成員函數(shù)在類(lèi)內(nèi)聲明,在類(lèi)外定義。但在類(lèi)外定義時(shí),要加關(guān)鍵字inline。定義與聲明放在同一.h文件中。說(shuō)明:12const成員函數(shù)const成員函數(shù):不修改數(shù)據(jù)成員的值,在程序中如果不小心修改了這個(gè)成員函數(shù)中的對(duì)象,則編譯器會(huì)產(chǎn)生一個(gè)語(yǔ)法錯(cuò)誤信息。const成員函數(shù)的定義方法:在函數(shù)的原型和定義中,在函數(shù)參數(shù)表和函數(shù)定義的左花括號(hào)之間加入const關(guān)鍵字。類(lèi)的成員函數(shù)允許重載,允許帶缺省參數(shù)值。132.2.2構(gòu)造函數(shù)性質(zhì):與類(lèi)同名、無(wú)返回類(lèi)型在對(duì)象創(chuàng)建時(shí)由系統(tǒng)自動(dòng)調(diào)用允許重載、帶缺省值如果類(lèi)中未聲明,則系統(tǒng)自動(dòng)生成一個(gè)缺省形式的構(gòu)造函數(shù),形如:類(lèi)名(){}作用:對(duì)象的初始化14構(gòu)造函數(shù)舉例---CCircle類(lèi)classCCircle{public:

CCircle()//無(wú)參(缺省)構(gòu)造函數(shù)

{ radius=1;}CCircle(doubler)//帶參構(gòu)造函數(shù)

……private: doubleradius;};CCircle::CCircle(doubler){radius=r>0?r:1;}兩個(gè)構(gòu)造函數(shù)合成一個(gè)帶缺省值的構(gòu)造函數(shù)CCircle(doubler=1);//構(gòu)造函數(shù)原型CCircle::CCircle(doubler)//構(gòu)造函數(shù)定義{radius=r>0?r:1; }15拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),其形參為本類(lèi)對(duì)象的引用。class類(lèi)名{public:

類(lèi)名(形參);//構(gòu)造函數(shù)類(lèi)名(類(lèi)名&對(duì)象名);//拷貝構(gòu)造函數(shù)

……};類(lèi)名::類(lèi)名(類(lèi)名&對(duì)象名)//拷貝構(gòu)造函數(shù)的實(shí)現(xiàn){函數(shù)體}16拷貝構(gòu)造函數(shù)舉例classCCircle{public:

CCircle(floatm=1,floatn=1,floatr=1);

CCircle(constCCircle&c)//拷貝構(gòu)造函數(shù)

{ radius=c.radius; }……};17當(dāng)用類(lèi)的一個(gè)對(duì)象去初始化該類(lèi)的另一個(gè)對(duì)象時(shí)系統(tǒng)自動(dòng)調(diào)用它實(shí)現(xiàn)對(duì)象的拷貝賦值。voidmain(){

CCirclec1;

CCircle

c2(c1);//拷貝構(gòu)造函數(shù)被調(diào)用}拷貝構(gòu)造函數(shù)調(diào)用之一18拷貝構(gòu)造函數(shù)調(diào)用之二若函數(shù)的形參為類(lèi)對(duì)象按值傳遞時(shí),實(shí)參賦值給形參,將自動(dòng)調(diào)用復(fù)制構(gòu)造函數(shù),例如:voidfun1(CCirclec){

cout<<c.GetRadius()<<endl;}voidmain(){

CCirclec1(2,2,10);fun1(c1);//調(diào)用復(fù)制構(gòu)造函數(shù)

}

19當(dāng)函數(shù)的返回值是類(lèi)對(duì)象時(shí),系統(tǒng)自動(dòng)調(diào)用復(fù)制構(gòu)造函數(shù)。例如:CCirclefun2(){

CCirclec2(10);returnc2;//調(diào)用復(fù)制構(gòu)造函數(shù)}voidmain(){

CCirclec3;c3=fun2();}拷貝構(gòu)造函數(shù)調(diào)用之三20對(duì)于任何類(lèi),如果程序員沒(méi)有定義拷貝構(gòu)造函數(shù),則系統(tǒng)自動(dòng)生成一個(gè)拷貝構(gòu)造函數(shù),這種拷貝構(gòu)造函數(shù)在執(zhí)行時(shí),只是進(jìn)行簡(jiǎn)單的成員復(fù)制,這對(duì)于含有指針成員的類(lèi)是非常危險(xiǎn)的,在這種情況下,必須自定義拷貝構(gòu)造函數(shù)。拷貝構(gòu)造函數(shù)說(shuō)明212.2.3析構(gòu)函數(shù)作用:是釋放對(duì)象所占的動(dòng)態(tài)內(nèi)存空間。

特點(diǎn):函數(shù)名:~類(lèi)名();沒(méi)有參數(shù),也不返回任何值不允許重載如果類(lèi)中未定義析構(gòu)函數(shù),編譯器將自動(dòng)生成一個(gè)缺省的析構(gòu)函數(shù)。形如:~類(lèi)名(){}22在下列兩種情況下會(huì)被自動(dòng)調(diào)用:

對(duì)象定義在一個(gè)函數(shù)體中,該函數(shù)調(diào)用結(jié)束后,自動(dòng)調(diào)用析構(gòu)函數(shù);用new生成的動(dòng)態(tài)對(duì)象,當(dāng)使用delete刪除時(shí),自動(dòng)調(diào)用析構(gòu)函數(shù)。通常利用析構(gòu)函數(shù)刪除對(duì)象中指針成員所指向的動(dòng)態(tài)存儲(chǔ)空間,當(dāng)類(lèi)中沒(méi)有指針成員時(shí),則不需要定義析構(gòu)函數(shù)。析構(gòu)函數(shù)的調(diào)用232.2.4對(duì)象的定義和使用類(lèi)的對(duì)象是該類(lèi)的某一特定實(shí)體,即類(lèi)類(lèi)型的變量。聲明形式:

類(lèi)名對(duì)象名;例:

CCircleC1;

CCircle*pCircle;

CCircle

ArrayCircle[3];24類(lèi)成員的訪(fǎng)問(wèn)方式類(lèi)內(nèi)成員互訪(fǎng)直接使用成員名可以訪(fǎng)問(wèn)任意屬性成員類(lèi)外訪(fǎng)問(wèn)只能訪(fǎng)問(wèn)

public

屬性的成員使用“對(duì)象名.成員名”方式使用“對(duì)象指針名->成員名”方式25classTime{public:

inthour;

intminute;};Timet,*p;p=&t;cout<<p->hour;p->hour(*p).hourt.hour26this指針在C++中為每個(gè)非靜態(tài)成員函數(shù)提供了一個(gè)名字為this的指針,當(dāng)進(jìn)行成員函數(shù)調(diào)用時(shí),系統(tǒng)自動(dòng)將調(diào)用此成員函數(shù)的對(duì)象的地址作為一個(gè)隱含的參數(shù)傳遞給this指針,即讓this指針指向調(diào)用此成員函數(shù)的對(duì)象,從而使成員函數(shù)知道該對(duì)哪個(gè)對(duì)象進(jìn)行操作。使用this指針,保證了每個(gè)對(duì)象可以擁有不同的數(shù)據(jù)成員,但處理這些數(shù)據(jù)成員的代碼可以被所有的對(duì)象共享。27例2.2類(lèi)的應(yīng)用舉例(教材28頁(yè))一圓型游泳池如圖所示,現(xiàn)需要在其周?chē)ㄒ粓A型過(guò)道,并在其四周?chē)蠔艡?。柵欄價(jià)格為35元/米,過(guò)道造價(jià)為20元/平方米。過(guò)道寬度為3米,游泳池半徑由鍵盤(pán)輸入。要求編程計(jì)算并輸出過(guò)道和柵欄的造價(jià)。游泳池過(guò)道282.2.5靜態(tài)類(lèi)成員

創(chuàng)建了一個(gè)對(duì)象,則這個(gè)對(duì)象將擁有所有類(lèi)中的成員,如果某個(gè)數(shù)據(jù)對(duì)所有對(duì)象都一樣,則這個(gè)數(shù)據(jù)只要有一個(gè)拷貝,而不是每個(gè)對(duì)象都重復(fù)定義這個(gè)數(shù)據(jù),形成內(nèi)存浪費(fèi)。簡(jiǎn)言之:一個(gè)數(shù)據(jù)拷貝,所有對(duì)象共享。這時(shí)可以使用靜態(tài)數(shù)據(jù)成員。靜態(tài)類(lèi)成員:使用關(guān)鍵字static進(jìn)行修飾的類(lèi)成員。靜態(tài)類(lèi)成員可以聲明為public、private或

protected。

291、靜態(tài)數(shù)據(jù)成員表示的是類(lèi)范圍中所有對(duì)象共享的信息,相當(dāng)于局部于類(lèi)中的“全局變量”,為該類(lèi)的所有對(duì)象共享。因?yàn)殪o態(tài)數(shù)據(jù)成員只有一個(gè)數(shù)據(jù)副本,所以可以節(jié)省存儲(chǔ)空間。2、靜態(tài)數(shù)據(jù)成員必須在文件作用域內(nèi)進(jìn)行初始化,而且只能初始化一次。1、靜態(tài)數(shù)據(jù)成員3、由于數(shù)據(jù)隱藏的需要,靜態(tài)數(shù)據(jù)成員通常被聲明為

私有的,而通過(guò)定義公有的靜態(tài)成員函數(shù)來(lái)訪(fǎng)問(wèn)靜態(tài)數(shù)據(jù)成員。30靜態(tài)數(shù)據(jù)成員的定義和初始化classCCircle{public:……private:……

staticint

NumOfObject;//程序中生成的對(duì)象的個(gè)數(shù)};intCCircle::NumOfObject=0;//靜態(tài)數(shù)據(jù)成員的初始化31

靜態(tài)成員函數(shù):是用關(guān)鍵字static進(jìn)行修飾的成員函數(shù)。

靜態(tài)成員函數(shù)沒(méi)有this指針,因此當(dāng)其訪(fǎng)問(wèn)非靜態(tài)數(shù)據(jù)成員時(shí),必須通過(guò)對(duì)象名或?qū)ο笾羔樤L(fǎng)問(wèn)。2、靜態(tài)成員函數(shù)定義格式:static成員函數(shù)的原型;32使用靜態(tài)類(lèi)成員(教材30頁(yè))

3、靜態(tài)成員的訪(fǎng)問(wèn)在類(lèi)內(nèi):可直接訪(fǎng)問(wèn)。在類(lèi)外:只能訪(fǎng)問(wèn)公有靜態(tài)成員類(lèi)名::成員名(常用)對(duì)象名.成員名(.和->)332.3繼承性和派生類(lèi)繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)的最重要的特點(diǎn)之一,是軟件重用的一種重要形式,是對(duì)實(shí)際問(wèn)題中分層特性的一種自然描述。繼承的實(shí)質(zhì):是從已有的類(lèi)建立新類(lèi)。通過(guò)繼承,派生類(lèi)自動(dòng)擁有基類(lèi)的所有成員(數(shù)據(jù)成員和成員函數(shù))基類(lèi)和派生類(lèi)單繼承和多繼承

342.3.1派生類(lèi)的定義class派生類(lèi)名:繼承方式基類(lèi)名{

成員聲明;};35繼承方式三種繼承方式:public(公有)、

private(私有)、

protected(保護(hù)),

表2-1繼承方式對(duì)派生類(lèi)的影響繼承方式說(shuō)

明public(公有)基類(lèi)的public和protected成員被派生類(lèi)繼承后,保持原來(lái)的訪(fǎng)問(wèn)屬性不變private(私有)基類(lèi)的public和protected成員被派生類(lèi)繼承后,變成派生類(lèi)的private成員protected(保護(hù))基類(lèi)的public和protected成員被派生類(lèi)繼承后,變成派生類(lèi)的protected成員36例2.3

類(lèi)的派生示例教材31頁(yè)

372.3.2派生類(lèi)的構(gòu)造函數(shù)與析構(gòu)函數(shù)基類(lèi)的構(gòu)造函數(shù)不能被繼承,需要在派生類(lèi)中負(fù)責(zé)基類(lèi)成員的初始化。通過(guò)在成員初始化表中顯式調(diào)用基類(lèi)的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)的單一繼承時(shí)的構(gòu)造函數(shù)派生類(lèi)名::派生類(lèi)名(基類(lèi)成員和本類(lèi)成員所需的形參):基類(lèi)名(實(shí)參){

本類(lèi)成員初始化;}38派生類(lèi)構(gòu)造函數(shù)與析構(gòu)函數(shù)的執(zhí)行順序在創(chuàng)建派生類(lèi)的對(duì)象時(shí),派生類(lèi)的構(gòu)造函數(shù)總是先調(diào)用其基類(lèi)的構(gòu)造函數(shù)來(lái)完成基類(lèi)成員的初始化。如果在基類(lèi)和派生類(lèi)中都包含其他類(lèi)的對(duì)象(即有對(duì)象成員),則在創(chuàng)建派生類(lèi)的對(duì)象時(shí),首先執(zhí)行基類(lèi)的對(duì)象成員的構(gòu)造函數(shù),接著執(zhí)行基類(lèi)的構(gòu)造函數(shù),然后執(zhí)行派生類(lèi)的對(duì)象成員的構(gòu)造函數(shù),最后才執(zhí)行派生類(lèi)的構(gòu)造函數(shù)。當(dāng)派生類(lèi)對(duì)象的生命周期結(jié)束時(shí),析構(gòu)函數(shù)的執(zhí)行順序和構(gòu)造函數(shù)的執(zhí)行順序正好相反。392.3.3多繼承如果一個(gè)派生類(lèi)有多個(gè)直接基類(lèi),則稱(chēng)為多繼承。多繼承意味著一個(gè)派生類(lèi)可以繼承多個(gè)基類(lèi)的成員,這種強(qiáng)大的功能支持了軟件的重用性,但可能會(huì)引起大量的二義性(歧義性)問(wèn)題。

401.多繼承的定義格式class<派生類(lèi)名>:[<繼承方式>]<基類(lèi)名>,[<繼承方式>]<基類(lèi)名>,…{[<派生類(lèi)的成員>]};其中,繼承方式的使用與單繼承完全相同。【例2.4】使用多繼承(教材35頁(yè))412.多繼承派生類(lèi)對(duì)象的初始化派生類(lèi)構(gòu)造函數(shù)名(總參數(shù)表列):基類(lèi)1構(gòu)造函數(shù)(參數(shù)列表),基類(lèi)2構(gòu)造函數(shù)(參數(shù)列表),基類(lèi)3構(gòu)造函數(shù)(參數(shù)列表){派生類(lèi)中新增數(shù)據(jù)成員初始化語(yǔ)句}先調(diào)用基類(lèi)的構(gòu)造函數(shù),再執(zhí)行派生類(lèi)構(gòu)造函數(shù)的函數(shù)體。調(diào)用基類(lèi)構(gòu)造函數(shù)的順序是按照聲明派生類(lèi)時(shí)基類(lèi)出現(xiàn)的順序。423.二義性問(wèn)題因不同基類(lèi)中可能含有同名成員引起的二義性:用基類(lèi)名加以限定,形如:基類(lèi)名::同名成員名,以明確指出所使用的成員是從哪個(gè)基類(lèi)繼承來(lái)的。因公共基類(lèi)使得派生類(lèi)中含有同名成員,因此也會(huì)產(chǎn)生二義性。為了消除這種二義性,也必須使用基類(lèi)名限定所訪(fǎng)問(wèn)的同名成員。43虛基類(lèi)解決多繼承中因公共基類(lèi)而產(chǎn)生的二義性問(wèn)題。聲明虛基類(lèi)的一般格式為:class<派生類(lèi)名>:virtual[<繼承方式>]<基類(lèi)名>{[<派生類(lèi)的成員>]};保留字virtual和繼承方式的相對(duì)位置無(wú)關(guān)緊要,但要放在基類(lèi)名之前,并且virtual只對(duì)緊跟其后的基類(lèi)名起作用。442.4多態(tài)性在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,把不同類(lèi)的對(duì)象收到相同的消息時(shí)產(chǎn)生多種不同的行為方式稱(chēng)為多態(tài)性。452.4.1兩種多態(tài)性聯(lián)編:將一個(gè)函數(shù)調(diào)用鏈接上相應(yīng)于函數(shù)體的代碼,這一過(guò)程稱(chēng)為函數(shù)聯(lián)編(簡(jiǎn)稱(chēng)聯(lián)編)。靜態(tài)聯(lián)編:在編譯階段完成;優(yōu)點(diǎn)是執(zhí)行速度快動(dòng)態(tài)聯(lián)編:在運(yùn)行時(shí)才能把函數(shù)調(diào)用與函數(shù)體聯(lián)系在一起。具有靈活性高,易于擴(kuò)充和維護(hù)等優(yōu)點(diǎn),但運(yùn)行效率較低。靜態(tài)聯(lián)編所支持的多態(tài)性稱(chēng)為編譯時(shí)的多態(tài)性,通過(guò)函數(shù)重載來(lái)實(shí)現(xiàn)。動(dòng)態(tài)聯(lián)編所支持的多態(tài)性稱(chēng)為運(yùn)行時(shí)的多態(tài)性,通過(guò)虛函數(shù)來(lái)實(shí)現(xiàn)。462.4.2編譯時(shí)的多態(tài)性【例2.6】編譯時(shí)的多態(tài)性(教材39頁(yè))472.4.3虛函數(shù)虛函數(shù)是實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編的基礎(chǔ)。虛函數(shù)的聲明:在函數(shù)原型之前加virtual。class<類(lèi)名>{public:

//虛函數(shù)的聲明

virtual<返回類(lèi)型><函數(shù)名>(<參數(shù)表>);};

//虛函數(shù)的定義<返回類(lèi)型><類(lèi)名>::<函數(shù)名>(<參數(shù)表>)

{…...}

48應(yīng)注意的問(wèn)題:應(yīng)該在類(lèi)層次結(jié)構(gòu)中需要多態(tài)性的最高層類(lèi)內(nèi)聲明虛函數(shù)。派生類(lèi)中與基類(lèi)虛函數(shù)原型完全相同的成員函數(shù),會(huì)自動(dòng)成為虛函數(shù)。不能把靜態(tài)成員函數(shù)、構(gòu)造函數(shù)和全局函數(shù)聲明為虛函數(shù)。析構(gòu)函數(shù)可以聲明為虛函數(shù)。通過(guò)聲明虛函數(shù)來(lái)使用C++提供的多態(tài)性機(jī)制時(shí),派生類(lèi)應(yīng)該從它的基類(lèi)公有派生。

492.使用虛函數(shù)必須合理調(diào)用虛函數(shù)才能實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編。只有使用基類(lèi)類(lèi)型的指針或引用調(diào)用虛函數(shù)時(shí),系統(tǒng)才以動(dòng)態(tài)聯(lián)編方式實(shí)現(xiàn)對(duì)虛函數(shù)的調(diào)用,才能獲得運(yùn)行時(shí)的多態(tài)性。通常都用指向第一次定義虛函數(shù)的基類(lèi)對(duì)象的指針或引用來(lái)調(diào)用虛函數(shù)。虛函數(shù)的使用(教材41頁(yè))503.純虛函數(shù)純虛函數(shù):在聲明時(shí)“初始化值”為0的函數(shù)。class<類(lèi)名>{public:virtual<返回類(lèi)型><函數(shù)名>(<參數(shù)表>)=0;};純虛函數(shù)不需要進(jìn)行定義51抽象類(lèi)帶有純虛函數(shù)的類(lèi)稱(chēng)為抽象類(lèi)。不能聲明抽象類(lèi)的對(duì)象,但可以聲明抽象類(lèi)的指針和引用。抽象類(lèi)只能作為基類(lèi)來(lái)使用。522.5友元類(lèi)的重要特性是對(duì)數(shù)據(jù)實(shí)現(xiàn)了封裝和隱藏,這樣能大大提高程序的質(zhì)量,特別是能夠提高軟件的可維護(hù)性。封裝也會(huì)帶來(lái)一些不便。如果在程序中為了訪(fǎng)問(wèn)對(duì)象的私有數(shù)據(jù)成員而頻繁調(diào)用公有成員函數(shù)時(shí),將會(huì)帶來(lái)較大開(kāi)銷(xiāo),從而降低程序的執(zhí)行效率,影響程序的性能。C++中引入了友元機(jī)制,一個(gè)類(lèi)可以賦予某些函數(shù)或類(lèi)(友元函數(shù)或友元類(lèi))訪(fǎng)問(wèn)它的私有成員的特權(quán),從而減少了開(kāi)銷(xiāo)。532.5.1友元函數(shù)能夠訪(fǎng)問(wèn)一個(gè)類(lèi)的私有部分而又不是該類(lèi)成員函數(shù)的函數(shù),稱(chēng)為該類(lèi)的友元函數(shù)。將一個(gè)函數(shù)聲明為類(lèi)的友元,就是在類(lèi)定義中該函數(shù)的原型前面加上關(guān)鍵字friend。如下所示:classA{friendvoidsetX(A&,int

);…};54友元函數(shù)說(shuō)明友元函數(shù)雖然在類(lèi)內(nèi)聲明,但它不是該類(lèi)的成員函數(shù),所以友元函數(shù)沒(méi)有this指針。友元關(guān)系的聲明與成員訪(fǎng)問(wèn)說(shuō)明符private、protected和public無(wú)關(guān),因此友元函數(shù)聲明可以放在類(lèi)定義中的任何地方?!纠?.8】使用友元函數(shù)計(jì)算兩點(diǎn)間的距離。55友元成員一個(gè)類(lèi)的成員函數(shù)也可以聲明為另一個(gè)類(lèi)的友元函數(shù)。把類(lèi)C1的成員函數(shù)func聲明為類(lèi)C2的友元函數(shù):classC1{

…voidfunc(…);

…};classC2{friendvoidC1::func(…);//聲明友元成員

…};voidC1::func(…)

//定義友元成員{…}562.5.2友元類(lèi)如果一個(gè)類(lèi)的所有成員函數(shù)都可以訪(fǎng)問(wèn)另一個(gè)類(lèi)的私有成員,則可以把這個(gè)類(lèi)聲明為另一個(gè)類(lèi)的友元類(lèi)。例如,把類(lèi)C1聲明為類(lèi)C2的友元類(lèi):

classC2{friendclassC1;

…};【例2.9】使用友元類(lèi)(教材47頁(yè))572.6模板模板是C++實(shí)現(xiàn)軟件重用的一種形式,是C++最強(qiáng)大的特性之一。利用模板,我們可以用一段代碼指定一組相關(guān)函數(shù)(稱(chēng)為模板函數(shù))或一組相關(guān)類(lèi)(稱(chēng)為模板類(lèi))。這樣能大幅度地節(jié)約程序代碼,顯著減少冗余信息,從而進(jìn)一步提高面向?qū)ο蟪绦虻目芍赜眯院涂删S護(hù)性。模板的功能很強(qiáng),用戶(hù)既可以定義類(lèi)模板,也可以定義函數(shù)模板,還可以使用C++標(biāo)準(zhǔn)模板庫(kù)(STL)中已有的模板。

582.6.1函數(shù)模板如果幾個(gè)函數(shù)的功能相同,實(shí)現(xiàn)算法也相同,只是所處理的數(shù)據(jù)的類(lèi)型不同,使用函數(shù)模板更簡(jiǎn)潔,更方便。1.函數(shù)模板的定義

template<class<數(shù)據(jù)類(lèi)型參數(shù)表>>

函數(shù)模板定義體59說(shuō)明template是C++的保留字,表示后面定義的是一個(gè)模板。<數(shù)據(jù)類(lèi)型參數(shù)表>形如<classT1,classT2,…>,T1,T2等是類(lèi)型參數(shù)(形式參數(shù)),函數(shù)模板定義體與普通函數(shù)的定義相同,只不過(guò)其中的有些數(shù)據(jù)類(lèi)型,例如返回值類(lèi)型,形參的類(lèi)型,局部變量的類(lèi)型等,要使用類(lèi)型參數(shù)表中的標(biāo)識(shí)符T1,T2等表示。602.函數(shù)模板的調(diào)用函數(shù)模板的調(diào)用格式有兩種:第一種格式:函數(shù)模板名(實(shí)參表)第二種格式:函數(shù)模板名<類(lèi)型實(shí)參

>(實(shí)參表)函數(shù)模板的調(diào)用過(guò)程:函數(shù)模板實(shí)例化,把模板的類(lèi)型參數(shù)T1,T2等用具體的數(shù)據(jù)類(lèi)型去替換。函數(shù)模板實(shí)例化后會(huì)得到一個(gè)具體的函數(shù),該函數(shù)稱(chēng)為模板函數(shù)。執(zhí)行模板函數(shù),完成所需要的功能。【例2.10】利用函數(shù)模板實(shí)現(xiàn)求兩個(gè)數(shù)據(jù)的較大值。(教材50頁(yè))613.函數(shù)模板的特點(diǎn)函數(shù)模板實(shí)際上代表了一組函數(shù),而不是一個(gè)具體函數(shù)。所以,函數(shù)模板必須先實(shí)例化,才能完成具體函數(shù)的功能。函數(shù)模板不具有隱式類(lèi)型轉(zhuǎn)換的能力。普通函數(shù)在進(jìn)行調(diào)用時(shí),如果實(shí)參的類(lèi)型與形參的類(lèi)型不同,則系統(tǒng)會(huì)自動(dòng)對(duì)參數(shù)類(lèi)型進(jìn)行隱式轉(zhuǎn)換,將實(shí)參的值轉(zhuǎn)換為函數(shù)所需的類(lèi)型(實(shí)際上是生成一個(gè)臨時(shí)值使用),然后再進(jìn)行函數(shù)調(diào)用。而函數(shù)模板不具有這種功能。

622.6.2類(lèi)模板1.定義類(lèi)模板(1)定義類(lèi)template<class<類(lèi)型參數(shù)表>>class<類(lèi)名>{…};(2)定義成員函數(shù)632.使用類(lèi)模板類(lèi)模板與函數(shù)模板一樣,也是代表一組類(lèi)。因此在使用類(lèi)模板時(shí)首先要把它實(shí)例化為一個(gè)具體的類(lèi),這個(gè)具體的類(lèi)稱(chēng)為模板類(lèi)。把類(lèi)模板實(shí)例化為模板類(lèi)的格式如下:類(lèi)名<具體數(shù)據(jù)類(lèi)型名>然后用模板類(lèi)聲明對(duì)象并使用這些對(duì)象完成所需要的功能。64#include<iostream>usingnamespacestd;template<classnumtype>classCompare{public:

Compare(numtype

a,numtypeb){x=a;y=b;}

numtypemax(){return(x>y)?x:y;}

numtypemin(){return(x<y)?x:y;}private:

numtype

x,y;};65intmain(){Compare<int>cmp1(3,7);

cout<<cmp1.max()<<"istheMaximumoftwointedernumbers."<<endl;

cout<<cmp1.min()<<"istheMinimumoftwointedernumbers."<<endl<<endl;Compare<float>cmp2(45.78,93.6);

cout<<cmp2.max()<<"istheMaximumoftwofloatnumbers."<<endl;

cout<<cmp2.min()<<"istheMinimumoftwofloatnumbers."<<endl<<endl;Compare<char>cmp3('a','A');

cout<<cmp3.max()<<"istheMaximumoftwocharacters."<<endl;

cout<<cmp3.min()<<"istheMinimumoftwocharacters."<<endl;return0;}663.模板與繼承(1)從類(lèi)模板派生出類(lèi)模板

template<classT>classCBase{

…};template<classT>classCDerived

:publicCBase<T>{

…};(2)從類(lèi)模板派生出普通類(lèi)template<classT>classCBase{

…};classCDerived

:publicCBase<int>{

…};67——獲取水仙花數(shù)

1.項(xiàng)目要求編寫(xiě)一個(gè)程序,獲取指定數(shù)是否為水仙花數(shù)。水仙花數(shù)應(yīng)該滿(mǎn)足下面條件:一個(gè)3位數(shù),其各位數(shù)字的立方和等于該數(shù)本身。例如,153是一個(gè)水仙花數(shù),因?yàn)?53=13+53+33。該程序要求可以判斷用戶(hù)輸入的數(shù)是否為水仙花數(shù),也可以獲取指定范圍內(nèi)的數(shù)(在100至10000內(nèi))是否為水仙花數(shù)。2.項(xiàng)目分析如果判斷一個(gè)數(shù)是否是水仙花數(shù),需要獲取該數(shù)每位的數(shù)值。這可以通過(guò)求余數(shù)的方法獲取每位的數(shù)值,然后獲取每位的立方并求和。通過(guò)將和值與該數(shù)進(jìn)行比較,可以判斷該數(shù)是否為水仙花數(shù)。

68——獲取水仙花數(shù)

3.項(xiàng)目實(shí)現(xiàn)創(chuàng)建一個(gè)工程Exam,該程序由類(lèi)Data判斷數(shù)是否為水仙花數(shù),并輸出。這就需要?jiǎng)?chuàng)建類(lèi)Data,該類(lèi)擁有兩個(gè)私有屬性:num和ntype。num為用戶(hù)輸入的數(shù),ntype為用戶(hù)選擇的操作類(lèi)型。ntype有以下兩種類(lèi)型。判斷用戶(hù)輸入的數(shù)是否為水仙花數(shù)。獲取指定范圍內(nèi)(在100~10000內(nèi))的水仙花數(shù)。

69類(lèi)Data含有5個(gè)成員函數(shù),說(shuō)明如下。Data(intnum):Data構(gòu)造函數(shù),參數(shù)num為用戶(hù)輸入的數(shù)。該函數(shù)需要初始化ntype為1。Data():Data構(gòu)造函數(shù),獲取指定范圍內(nèi)(在100~10000內(nèi))的水仙花數(shù)。該函數(shù)需要初始化ntype為2。GetResult():函數(shù)依據(jù)ntype執(zhí)行相應(yīng)的操作,并輸出結(jié)果。IsSpecial(int

nNum):判斷nNum是否為水仙花數(shù),是則返回t

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論