C++教程第2章.ppt_第1頁(yè)
C++教程第2章.ppt_第2頁(yè)
C++教程第2章.ppt_第3頁(yè)
C++教程第2章.ppt_第4頁(yè)
C++教程第2章.ppt_第5頁(yè)
已閱讀5頁(yè),還剩101頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第二章類與對(duì)象 主講教師 張亞玲教授 學(xué)習(xí)目標(biāo) 掌握類的概念理解對(duì)象與類的關(guān)系 掌握對(duì)象的創(chuàng)建和使用掌握構(gòu)造函數(shù) 析構(gòu)函數(shù)的概念及使用方法掌握內(nèi)存的動(dòng)態(tài)分配的概念和使用方法掌握對(duì)象數(shù)組和對(duì)象指針掌握函數(shù)調(diào)用中參數(shù)的傳遞掌握友元函數(shù)和友元類的定義及使用 類的定義格式 class類名 private 數(shù)據(jù)成員或成員函數(shù)protected 數(shù)據(jù)成員或成員函數(shù)public 數(shù)據(jù)成員或成員函數(shù) 聲明一個(gè)圖書類 分析 圖書都有書名 作者 出版社和價(jià)格 對(duì)于圖書的基本操作有輸入 輸出圖書信息 因此首先抽象出所有圖書都具有的屬性 書名 作者 出版社和價(jià)格 然后用成員函數(shù)實(shí)現(xiàn)對(duì)圖書信息的輸入和輸出 classBook private chartitle 20 author 10 publish 30 floatprice public voidInput voidPrint 說(shuō)明 類聲明中的private protected和public關(guān)鍵字可以按任意順序出現(xiàn) 為了使程序更加清晰 應(yīng)將私有成員 保護(hù)成員和公有成員歸類存放 默認(rèn)時(shí)的訪問(wèn)權(quán)限為私有的 private 對(duì)于一個(gè)具體的類 類聲明中的private protected和public三個(gè)部分不一定都要有 但至少應(yīng)該有其中一個(gè)部分 數(shù)據(jù)成員可以是任何數(shù)據(jù)類型 但不能用自動(dòng) auto 寄存器 register 或外部 extern 類型進(jìn)行說(shuō)明 由于類是一種數(shù)據(jù)類型 系統(tǒng)并不會(huì)為其分配內(nèi)存空間 所以不能在類聲明中給數(shù)據(jù)成員賦初值 錯(cuò)誤的類聲明 聲明一個(gè)長(zhǎng)方形類 分析 長(zhǎng)方形有長(zhǎng)和寬 對(duì)于長(zhǎng)方形可以計(jì)算其面積和周長(zhǎng) 因此抽象出所有長(zhǎng)方形都具有的屬性長(zhǎng)和寬 然后用成員函數(shù)實(shí)現(xiàn)求面積和求周長(zhǎng)運(yùn)算 classRectangle private doublelength 3 5 doublewidth 4 6 public doubleArea doublePerimeter 說(shuō)明 1 一般將類的聲明放在頭文件 h中 而將成員函數(shù)的實(shí)現(xiàn)放在 cpp文件中 2 類定義必須以 結(jié)束 成員函數(shù)的定義 返回類型類名 函數(shù)名 參數(shù)表 函數(shù)體 voidBook Input cin title author publish price voidBook Print cout title author publish price endl 說(shuō)明 如果在類外定義成員函數(shù) 則應(yīng)在所定義的成員函數(shù)名前綴上類名 在類名和函數(shù)名之間應(yīng)加上作用域運(yùn)算符 它說(shuō)明成員函數(shù)從屬于哪個(gè)類 例如上例中的 voidBook Input 表示成員函數(shù)Input是Book類中的函數(shù) 在定義成員函數(shù)時(shí) 對(duì)函數(shù)所帶的參數(shù) 不但要說(shuō)明它的類型 還要指出其參數(shù)名 在定義成員函數(shù)時(shí) 其返回類型一定要與函數(shù)原型聲明的返回類型匹配 對(duì)象的定義與使用 對(duì)象的定義先聲明類 然后在使用的時(shí)候再定義對(duì)象 定義格式與一般變量定義格式相同例如 Bookb1 b2 此時(shí)定義了b1和b2為Book類的兩個(gè)對(duì)象 類名對(duì)象名列表 說(shuō)明 必須定義了類以后 才能定義類的對(duì)象 多個(gè)對(duì)象之間用逗號(hào)分隔 聲明了一個(gè)類就聲明了一種類型 它并不能接收和存儲(chǔ)具體的值 只能作為生成具體對(duì)象的一種 樣板 只有定義了對(duì)象后 系統(tǒng)才為對(duì)象分配存儲(chǔ)空間 對(duì)象的使用 Bookb1 b1 Input 通過(guò)對(duì)象b1執(zhí)行輸入操作b1 Print 通過(guò)對(duì)象b1執(zhí)行輸出操作 例2 3 圖書類的完整程序 對(duì)象名 成員函數(shù)名 實(shí)參表 classBook 該段程序放在名為book h的文件中 private chartitle 20 author 10 publish 30 floatprice public voidInput voidPrint include iostream 該段程序放在名為book cpp的文件中usingnamespacestd include book h intmain Bookb1 b1 Input cout 運(yùn)行結(jié)果 endl b1 Print return0 voidBook Input cout title author publish price voidBook Print cout title author publish price endl defineN5 定義常量N表示有N個(gè)學(xué)生 student hstructStudent 聲明結(jié)構(gòu)體類型 用來(lái)表示學(xué)生 longlNum 學(xué)號(hào)charcName 12 姓名floatfGrade 成績(jī) classOurClass 聲明一個(gè)班級(jí)類 private Students N 定義N個(gè)學(xué)生public voidInput 輸入學(xué)生信息voidPrint 輸出學(xué)生信息voidSort 按學(xué)生成績(jī)進(jìn)行排序 思考 OurClass類定義的不妥之處 1 類名定義不妥 應(yīng)該為StudentClass 2 應(yīng)該補(bǔ)充屬性 classNamenumberleaderName 例2 4 學(xué)生成績(jī)管理 例1 1 的完整程序 include iostream student cppusingnamespacestd include student h intmain OurClasscl 定義對(duì)象stucl Input 輸入N個(gè)學(xué)生的信息 學(xué)號(hào) 姓名 成績(jī)cl Sort 按學(xué)生成績(jī)進(jìn)行排序cout s i lNum s i cName s i fGrade voidOurClass Sort inti j StudentTemp for i 0 i N 1 i for j i 1 j N j if s i fGrade s j fGrade 交換學(xué)生信息Temp s i s i s j s j Temp voidOurClass Print inti cout 學(xué)號(hào)姓名成績(jī) endl for i 0 i N i cout s i lNum s i cName s i fGrade endl 對(duì)象的賦值 同類型的變量 如整型 實(shí)型 結(jié)構(gòu)體類型等的變量可以利用賦值操作符 進(jìn)行賦值 對(duì)于同類型的對(duì)象也同樣適用 也就是說(shuō) 同類型的對(duì)象之間可以進(jìn)行賦值 這種賦值默認(rèn)通過(guò)成員復(fù)制進(jìn)行 當(dāng)對(duì)象進(jìn)行賦值時(shí) 對(duì)象的每一個(gè)成員逐一復(fù)制 賦值 給另一個(gè)對(duì)象的同一成員 例2 5 對(duì)象的賦值 平面上的點(diǎn)的賦值 注意 在使用對(duì)象賦值語(yǔ)句進(jìn)行賦值時(shí) 兩個(gè)對(duì)象的類型必須相同 賦值兼容規(guī)則除外 兩個(gè)對(duì)象間的賦值 僅僅使這些對(duì)象中的數(shù)據(jù)相同 而兩個(gè)對(duì)象仍然是彼此獨(dú)立的 各自有自己的內(nèi)存空間 如果類中存在指針 則不能簡(jiǎn)單的將一個(gè)對(duì)象的值賦給另一個(gè)對(duì)象 否則可能會(huì)產(chǎn)生錯(cuò)誤 classPoint 該段程序放在名為point h的文件中private intx y public voidSetPoint inta intb voidPrint include iomanip 該段程序放在名為point cpp的文件中 include iostream usingnamespacestd include point h intmain Pointp1 p2 定義對(duì)象p1 p2p1 SetPoint 3 5 cout p1 endl p1 Print cout p2 endl p2 Print p2 p1 對(duì)象賦值cout p2 p1 endl p2 Print return0 voidPoint SetPoint inta intb x a y b voidPoint Print cout x x setw 5 y y endl 構(gòu)造函數(shù)和析構(gòu)函數(shù) 如果變量在使用之前沒(méi)有正確初始化或清除 將導(dǎo)致程序出錯(cuò) 因此要求對(duì)對(duì)象必須正確地進(jìn)行初始化 構(gòu)造函數(shù)的功能是在創(chuàng)建對(duì)象時(shí) 給數(shù)據(jù)成員賦初值 即對(duì)象的初始化 思考 如何給一個(gè)對(duì)象的私有屬性初始化值 2種方法 構(gòu)造函數(shù) 定義構(gòu)造函數(shù)原型的格式為 在類外定義構(gòu)造函數(shù)的定義格式為 類名 形參列表 類名 類名 形參列表 函數(shù)語(yǔ)句 說(shuō)明 構(gòu)造函數(shù)的名字必須與類名相同 構(gòu)造函數(shù)可以有任意類型的參數(shù) 但是沒(méi)有返回值類型 也不能指定為void類型 定義對(duì)象時(shí) 編譯系統(tǒng)會(huì)自動(dòng)地調(diào)用構(gòu)造函數(shù) 通常構(gòu)造函數(shù)被定義在公有部分 如果沒(méi)有定義構(gòu)造函數(shù) 系統(tǒng)會(huì)自動(dòng)生成一個(gè)缺省的構(gòu)造函數(shù) 只負(fù)責(zé)對(duì)象的創(chuàng)建 不做任何初始化工作 構(gòu)造函數(shù)可以重載 例2 6 構(gòu)造函數(shù)應(yīng)用舉例 輸出日期 classDate 該段程序放在名為date h的文件中private intyear month day public Date inty intm intd voidPrint include iostream 該段程序放在名為date cpp的文件中usingnamespacestd include date h intmain Datetoday 2000 3 1 cout todayis today Print return0 Date Date inty intm intd year y month m day d voidDate Print cout year month day endl 注意 在實(shí)際應(yīng)用中 通常需要給每個(gè)類定義構(gòu)造函數(shù) 如果沒(méi)有給類定義構(gòu)造函數(shù) 則系統(tǒng)自動(dòng)生成一個(gè)默認(rèn)的構(gòu)造函數(shù) 類名 構(gòu)造函數(shù)名 構(gòu)造函數(shù)可以不帶參數(shù) Point Point x 0 y 0 classPoint private intx y public Point 注意 構(gòu)造函數(shù)也可采用構(gòu)造初始化表對(duì)數(shù)據(jù)成員進(jìn)行初始化 classDate private intyear month day public Date inty intm intd year y month m day d 構(gòu)造函數(shù)初始化表對(duì)數(shù)據(jù)成員進(jìn)行初始化 注意 如果數(shù)據(jù)成員是數(shù)組 則應(yīng)在構(gòu)造函數(shù)中使用相關(guān)語(yǔ)句進(jìn)行初始化 classStudent private charname 10 intage public Student charna inta Student Student charna inta age a strcpy name na name是字符數(shù)組 所以用strcpy函數(shù)進(jìn)行初始化 析構(gòu)函數(shù) 析構(gòu)函數(shù)的功能是在對(duì)象刪除之前 用它來(lái)做一些內(nèi)存釋放等清理工作 它的功能與構(gòu)造函數(shù)的功能正好相反 析構(gòu)函數(shù) 定義析構(gòu)函數(shù)的一般格式析構(gòu)函數(shù)的特點(diǎn)析構(gòu)函數(shù)名是由 和類名組成的 析構(gòu)函數(shù)沒(méi)有參數(shù) 也沒(méi)有返回值 而且也不能重載 通常析構(gòu)函數(shù)被定義在公有部分 并由系統(tǒng)自動(dòng)調(diào)用 一個(gè)類中有且僅有一個(gè)析構(gòu)函數(shù) 且應(yīng)為public 類名 析構(gòu)函數(shù) 例2 7 構(gòu)造函數(shù)與析構(gòu)函數(shù)的執(zhí)行順序 Point類的多個(gè)對(duì)象的創(chuàng)建與釋放 例2 8 對(duì)象定義在函數(shù)體內(nèi) 析構(gòu)函數(shù)的執(zhí)行情況 例2 9 復(fù)合語(yǔ)句中對(duì)象的析構(gòu)函數(shù)的執(zhí)行情況 例2 7 classPoint 該段程序放在名為point h的文件中private intx y public Point inta intb Point include iostream 該段程序放在名為point cpp的文件中usingnamespacestd include point h intmain Pointp1 1 2 p2 3 5 return0 Point Point inta intb 定義構(gòu)造函數(shù) cout constructor endl x a y b cout x y endl Point Point 定義析構(gòu)函數(shù) cout destructor endl cout x y endl 例2 8 classComplex complex hprivate doublereal imag public Complex doubler doublei Complex include iostream usingnamespacestd include complex h voidfun Complexc intmain cout insidemain endl Complexc1 1 1 2 2 fun c1 cout outsidemain endl return0 Complex Complex doubler doublei cout constructor endl real r imag i Complex Complex cout destructor endl voidfun Complexc cout insidefun endl 思考 是不是每個(gè)類都需要有析構(gòu)函數(shù) 具有什么特點(diǎn)的類必須提供析構(gòu)函數(shù) 內(nèi)存的動(dòng)態(tài)分配 用戶存儲(chǔ)區(qū)空間分三個(gè)部分 程序區(qū) 代碼區(qū) 靜態(tài)存儲(chǔ)區(qū) 數(shù)據(jù)區(qū) 和動(dòng)態(tài)存儲(chǔ)區(qū) 棧區(qū)和堆區(qū) 代碼區(qū)存放程序代碼 程序運(yùn)行前就分配存儲(chǔ)空間 數(shù)據(jù)區(qū)存放常量 靜態(tài)變量 全局變量等 棧區(qū)存放局部變量 函數(shù)參數(shù) 函數(shù)返回值和臨時(shí)變量等 堆區(qū)是程序空間中存在的一些空閑存儲(chǔ)單元 這些空閑存儲(chǔ)單元組成堆 在堆中創(chuàng)建的數(shù)據(jù)對(duì)象稱為堆對(duì)象 當(dāng)創(chuàng)建對(duì)象時(shí) 堆中的一些存儲(chǔ)單元從未分配狀態(tài)變?yōu)橐逊峙錉顟B(tài) 當(dāng)刪除所創(chuàng)建的堆對(duì)象時(shí) 這些存儲(chǔ)單元從已分配狀態(tài)又變?yōu)槲捶峙錉顟B(tài) 當(dāng)堆對(duì)象不再使用時(shí) 應(yīng)予以刪除 回收其所占用的動(dòng)態(tài)內(nèi)存 運(yùn)算符new 在C 程序中 運(yùn)算符new的功能是實(shí)現(xiàn)內(nèi)存的動(dòng)態(tài)分配 new運(yùn)算符的使用格式包括三種形式 說(shuō)明T是一個(gè)數(shù)據(jù)類型名 表示在堆中建立一個(gè)T類型的數(shù)據(jù) 初始值列表可以省略 例如 int p float p1 p newint 100 讓p指向一個(gè)類型為整型的堆地址 該地址中存放值100p1 newfloat 讓p1指向一個(gè)類型為實(shí)型的堆地址 指針變量 newT 指針變量 newT 初始值列表 指針變量 newT 元素個(gè)數(shù) 運(yùn)算符new 用new創(chuàng)建堆對(duì)象的格式 類名 指針名 new類名 構(gòu)造函數(shù)參數(shù) Complex c1 newComplex 1 1 2 2 創(chuàng)建對(duì)象 c1 并調(diào)用構(gòu)造函數(shù)初始化數(shù)據(jù)成員real imag為1 1 2 2new后面的類的類型后面是否跟參數(shù)取決于構(gòu)造函數(shù) classDate private intyear month day public Date intmain Date today newDate Date Date year 2001 month 12 day 3 運(yùn)算符new new返回一個(gè)指定的合法數(shù)據(jù)類型的內(nèi)存空間的首地址 指針 若分配不成功 則返回一個(gè)空指針 new可以為數(shù)組動(dòng)態(tài)分配內(nèi)存空間 這時(shí)應(yīng)該在類型名后面指明數(shù)組大小 其中 元素個(gè)數(shù)是一個(gè)整型數(shù)值 可以是常數(shù)也可以是變量 指針類型應(yīng)與數(shù)組類型一致 例如 intn p cin n p newint n 表示new為具有n個(gè)元素的整型數(shù)組分配了內(nèi)存空間 并將首地址賦給了指針p 運(yùn)算符new new不能對(duì)動(dòng)態(tài)分配的數(shù)組存儲(chǔ)區(qū)進(jìn)行初始化 例如 int p p newint 10 0 錯(cuò)誤 不能對(duì)動(dòng)態(tài)分配的數(shù)組進(jìn)行初始化用new分配的空間 使用結(jié)束后只能用delete顯式地釋放 否則這部分空間將不能回收而造成內(nèi)存泄露 運(yùn)算符delete 運(yùn)算符delete用來(lái)釋放動(dòng)態(tài)變量或動(dòng)態(tài)數(shù)組所占的內(nèi)存空間 delete運(yùn)算符的應(yīng)用格式如下釋放動(dòng)態(tài)變量所占的內(nèi)存空間例如 int p newint deletep 釋放指針p所指向的動(dòng)態(tài)內(nèi)存空間 delete指針變量名 delete 指針變量名 運(yùn)算符delete 釋放動(dòng)態(tài)數(shù)組所占的內(nèi)存空間例如 int p p newint 10 delete p 釋放為數(shù)組動(dòng)態(tài)分配的內(nèi)存說(shuō)明new和delete需要配套使用 如果搭配錯(cuò)了 程序運(yùn)行時(shí)將會(huì)發(fā)生不可預(yù)知的錯(cuò)誤 在用delete釋放指針?biāo)傅目臻g時(shí) 必須保證這個(gè)指針?biāo)傅目臻g是用new申請(qǐng)的 并且只能釋放一次 否則將產(chǎn)生指針懸掛問(wèn)題 見(jiàn)第七章運(yùn)算符重載 運(yùn)算符delete 如果在程序中用new申請(qǐng)了空間 就應(yīng)該在結(jié)束程序前釋放所有申請(qǐng)的空間 這樣才能保證堆內(nèi)存的有效利用 當(dāng)delete用于釋放由new創(chuàng)建的數(shù)組的連續(xù)內(nèi)存空間時(shí) 無(wú)論是一維數(shù)組還是多維數(shù)組 指針變量名前必須使用 且 內(nèi)沒(méi)有數(shù)字 例2 10 動(dòng)態(tài)創(chuàng)建類Point的對(duì)象 classPoint point h private intx y public Point inta intb Point include iostream point cppusingnamespacestd include point h intmain Point p newPoint 1 3 動(dòng)態(tài)創(chuàng)建對(duì)象 自動(dòng)調(diào)用構(gòu)造函數(shù)deletep 刪除對(duì)象 自動(dòng)調(diào)用析構(gòu)函數(shù)return0 Point Point inta intb cout constructor endl x a y b Point Point cout destructor endl 一個(gè)重要問(wèn)題 如果一個(gè)類中定義了動(dòng)態(tài)申請(qǐng)的數(shù)據(jù)成員 則不得使用對(duì)象賦值進(jìn)行該類兩個(gè)對(duì)象之間的賦值 思考 如果違反產(chǎn)生什么后果 對(duì)象數(shù)組和對(duì)象指針 對(duì)象數(shù)組數(shù)組的元素可以是基本數(shù)據(jù)類型的數(shù)據(jù) 也可以是用戶自定義數(shù)據(jù)類型的數(shù)據(jù) 對(duì)象數(shù)組是指每一個(gè)數(shù)組元素都是對(duì)象的數(shù)組 對(duì)象數(shù)組的元素是對(duì)象 它不僅具有數(shù)據(jù)成員 而且還有成員函數(shù) 聲明對(duì)象數(shù)組的形式 類名數(shù)組名 下標(biāo)表達(dá)式 數(shù)組名 下標(biāo) 成員函數(shù) 對(duì)象數(shù)組的引用形式 對(duì)象數(shù)組 實(shí)際上 不僅可以說(shuō)明基本數(shù)據(jù)類型或符合數(shù)據(jù)類型的數(shù)組 在程序中定義了一個(gè)類之后 還可以說(shuō)明該類對(duì)象的數(shù)組 因?yàn)轭悓?shí)質(zhì)上是一個(gè)數(shù)據(jù)類型 因此說(shuō)明對(duì)象數(shù)組的方法與說(shuō)明普通數(shù)組的方法非常相似 惟一需要進(jìn)一步講述的是初始化對(duì)象數(shù)組的方法 1 使用缺省構(gòu)造函數(shù)完成初始化方法2 使用帶參數(shù)的構(gòu)造函數(shù)初始化數(shù)組 參見(jiàn)P106 對(duì)象數(shù)組 定義 類名數(shù)組名 元素個(gè)數(shù) 訪問(wèn)方法 通過(guò)下標(biāo)訪問(wèn)數(shù)組名 下標(biāo) 成員名 數(shù)組 對(duì)象數(shù)組初始化 數(shù)組中每一個(gè)元素對(duì)象被創(chuàng)建時(shí) 系統(tǒng)都會(huì)調(diào)用構(gòu)造函數(shù)類初始化該對(duì)象 通過(guò)初始化列表賦值 例 LocationA 2 Location 1 2 Location 3 4 如果沒(méi)有為數(shù)組元素指定顯式初始值 數(shù)組元素使用缺省值初始化 調(diào)用缺省構(gòu)造函數(shù) 數(shù)組 數(shù)組元素所屬類的構(gòu)造函數(shù) 不定義構(gòu)造函數(shù) 則采用缺省構(gòu)造函數(shù) 各元素對(duì)象的初值要求為相同的值時(shí) 可以定義出具有缺省形參值的構(gòu)造函數(shù) 各元素對(duì)象的初值要求為不同的值時(shí) 需要定義帶形參 無(wú)缺省值 的構(gòu)造函數(shù) 當(dāng)數(shù)組中每一個(gè)對(duì)象被刪除時(shí) 系統(tǒng)都要調(diào)用一次析構(gòu)函數(shù) 數(shù)組 對(duì)象數(shù)組應(yīng)用舉例 Location h if defined LOCATION H define LOCATION HclassLocation public Location Location intxx intyy Location voidMove intx inty intGetX returnX intGetY returnY private intX Y endif include include Location h Location Location X Y 0 cout DefaultConstructorcalled endl Location Location intxx intyy X xx Y yy cout Constructorcalled endl Locatuon Location cout Destructorcalled endl voidLocation Move intx inty X x Y y intmain cout Enteringmain endl LocationA 2 for inti 0 i 2 i A i Move i 10 i 20 cout Exitingmain endl return0 運(yùn)行結(jié)果 Enteringmain DefaultConstructorcalled DefaultConstructorcalled Exitingmain Destructorcalled Destructorcalled 對(duì)象數(shù)組和對(duì)象指針 例2 11 對(duì)象數(shù)組的應(yīng)用 求圓的面積 例2 12 輸出若干個(gè)平面上的點(diǎn)訪問(wèn)一個(gè)對(duì)象既可以通過(guò)對(duì)象名訪問(wèn) 也可以通過(guò)對(duì)象地址訪問(wèn) 對(duì)象指針就是用于存放對(duì)象地址的變量 對(duì)象指針遵循一般變量指針的各種規(guī)則 聲明對(duì)象指針的一般語(yǔ)法形式為 類名 對(duì)象指針名 對(duì)象指針名 成員名 例2 11 classCircle 該段程序放在名為circle h的文件中 private doubleradius public Circle doubler doubleArea Circle include iostream 該段程序放在名為circle cpp的文件中usingnamespacestd include circle h intmain Circlec 3 1 3 5 inti for i 0 i 3 i cout c i Area endl return0 Circle Circle doubler cout construct endl radius r doubleCircle Area return3 14 radius radius Circle Circle cout destruct endl 例 2 12 輸出若干個(gè)平面上的點(diǎn) classPoint point hprivate intx y public Point inta intb voidPrint include iostream point cppusingnamespacestd include point h intmain Pointob 3 Point 1 2 Point 3 4 Point 5 6 inti for i 0 i 3 i ob i Print return0 Point Point inta intb x a y b voidPoint Print cout x y endl 在定義對(duì)象數(shù)組ob時(shí)系統(tǒng)會(huì)自動(dòng)調(diào)用構(gòu)造函數(shù)進(jìn)行初始化 然而此時(shí)構(gòu)造函數(shù)的參數(shù)是2個(gè) 因此就需要通過(guò)直接調(diào)用構(gòu)造函數(shù)給對(duì)象數(shù)組賦值 即 Pointob 3 Point 1 2 Point 3 4 Point 5 6 從而實(shí)現(xiàn)對(duì)象數(shù)組的初始化操作 classPoint point hprivate intx y public Point inta intb voidPrint include iostream point cppusingnamespacestd include point h intmain Pointob 3 Point 1 2 Point 3 4 Point 5 6 inti for i 0 i 3 i ob i Print return0 Point Point inta intb x a y b voidPoint Print cout x y endl 對(duì)象指針 例如 Circle c1 c 3 c1 c3 Area 錯(cuò)誤 不能使用沒(méi)有初始化的對(duì)象指針 對(duì)象指針 例2 13 用對(duì)象指針訪問(wèn)Circle類的成員函數(shù) 例2 14 用對(duì)象指針引用Circle類的對(duì)象數(shù)組 例2 13 intmain Circle c newCircle 3 coutArea endl deletec return0 例2 14 intmain Circlec 3 1 3 5 Circle p c for pArea endl return0 自引用指針this 當(dāng)定義了一個(gè)類的若干對(duì)象后 每個(gè)對(duì)象都有屬于自己的數(shù)據(jù)成員 而同一類的不同對(duì)象將共同擁有一份成員函數(shù)的拷貝 那么在執(zhí)行不同對(duì)象所對(duì)應(yīng)的成員函數(shù)時(shí) 各成員函數(shù)是如何分辨出當(dāng)前調(diào)用自己的是哪個(gè)對(duì)象呢 使用this指針時(shí)應(yīng)該注意以下幾點(diǎn) this指針是一個(gè)const指針 不能在程序中修改它或給它賦值 this指針是一個(gè)局部數(shù)據(jù) 它的作用域僅在一個(gè)對(duì)象的內(nèi)部 靜態(tài)成員函數(shù)不屬于任何一個(gè)對(duì)象 在靜態(tài)成員函數(shù)中沒(méi)有this指針 例2 16 this應(yīng)用舉例 通過(guò)成員函數(shù)copy實(shí)現(xiàn)Square類對(duì)象的賦值 C 為非靜態(tài)成員函數(shù)提供了一個(gè)名字為this的指針 這個(gè)指針?lè)Q為自引用指針 每當(dāng)對(duì)象調(diào)用成員函數(shù)時(shí) 系統(tǒng)就將該對(duì)象的地址賦給this指針 這時(shí)C 編譯器將根據(jù)this指針?biāo)赶虻膶?duì)象來(lái)確定應(yīng)該引用哪一個(gè)對(duì)象的數(shù)據(jù)成員 例2 15 輸出不同正方形的面積 classSquare square h private doublelength public Square doublel doubleArea include iostream square cppusingnamespacestd include square h intmain Squares1 3 s2 5 coutlength l doubleSquare Area returnlength length 例2 16 this應(yīng)用舉例 通過(guò)成員函數(shù)copy實(shí)現(xiàn)Square類對(duì)象的賦值 classSquare square h private doublelength public Square doublel doubleArea voidcopy Squares include iostream square cppusingnamespacestd include square h intmain Squares1 3 s2 5 cout beforecopy endl cout s1areais s1 Area endl cout aftercopy endl s1 copy s2 cout s1areais s1 Area endl return0 Square Square doublel length l doubleSquare Area returnlength length voidSquare copy Squares if this 函數(shù)參數(shù)的傳遞機(jī)制 使用對(duì)象作為函數(shù)參數(shù)當(dāng)進(jìn)行函數(shù)調(diào)用時(shí) 需要給形參分配存儲(chǔ)單元 形參和實(shí)參結(jié)合是值傳遞 實(shí)參將自己的值傳遞給形參 形參實(shí)際上是實(shí)參的副本 這是一種單向傳遞 形參的變化不會(huì)影響到實(shí)參 例2 17 對(duì)象作為函數(shù)參數(shù) 求平面上的點(diǎn)向東 向北移動(dòng)1格的新坐標(biāo)使用對(duì)象指針作為函數(shù)參數(shù)當(dāng)進(jìn)行函數(shù)調(diào)用時(shí) 需要給形參分配存儲(chǔ)單元 形參和實(shí)參的結(jié)合是地址傳遞 實(shí)參將自己的地址傳遞給形參 形參的變化會(huì)直接影響到實(shí)參 函數(shù)參數(shù)的傳遞機(jī)制 使用對(duì)象引用作為函數(shù)參數(shù)當(dāng)進(jìn)行函數(shù)調(diào)用時(shí) 在內(nèi)存中并沒(méi)有產(chǎn)生實(shí)參的副本 它是直接對(duì)實(shí)參操作 這種方式是雙向傳遞 形參的變化會(huì)直接影響到實(shí)參 與指針作函數(shù)參數(shù)比較 這種方式更容易使用 更清晰 而且當(dāng)參數(shù)傳遞的數(shù)據(jù)較大時(shí) 用引用比用一般變量傳遞參數(shù)的效率和所占空間都好 引用 即一個(gè)變量的別名 如果用于形參 則和實(shí)參直接公用內(nèi)存單元 例3 6輸入兩整數(shù) 交換后輸出 includevoidSwap inta intb intmain intx 5 y 10 cout x x y y endl Swap x y cout x x y y endl return0 函數(shù)的定義與使用 voidSwap inta intb intt t a a b b t 運(yùn)行結(jié)果 x 5y 10 x 5y 10 例輸入兩整數(shù) 交換后輸出 includevoidSwap int voidSwap int 運(yùn)行結(jié)果 x 5y 10 x 10y 5 例引用調(diào)用舉例 include includevoidfiddle intin1 int 函數(shù)的定義與使用 voidfiddle intin1 int 運(yùn)行結(jié)果 Thevaluesare712Thevaluesare107112Thevaluesare7112 例2 19 友元 類的主要特點(diǎn)之一是數(shù)據(jù)隱藏 也就是類的私有成員只能通過(guò)它的成員函數(shù)來(lái)訪問(wèn) 有沒(méi)有辦法允許在類外對(duì)某個(gè)對(duì)象的私有成員進(jìn)行操作呢 在C 中提供了友元機(jī)制來(lái)解決上述問(wèn)題 友元既可以是不屬于任何類的一般函數(shù) 也可以是另一個(gè)類的成員函數(shù) 還可以是整個(gè)的一個(gè)類 這時(shí) 這個(gè)類中的所有成員函數(shù)都可以成為友元函數(shù) 友元 在進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì)時(shí) 充分 合理的使用程序語(yǔ)言提供的封裝機(jī)制 能大大提高程序的質(zhì)量 特別是能夠提高軟件的可維護(hù)性 但是 在某些情況下 封裝也會(huì)帶來(lái)一些負(fù)面效應(yīng) 如果為了訪問(wèn)對(duì)象的私有數(shù)據(jù)成員而在程序中多次調(diào)用公有的成員函數(shù) 則會(huì)帶來(lái)較大開(kāi)銷 從而降低程序的運(yùn)行效率 參見(jiàn)P110 友元機(jī)制是對(duì)封裝機(jī)制的補(bǔ)充 利用這種機(jī)制 一個(gè)類可以賦予某些函數(shù)訪問(wèn)它的私有成員的特權(quán) 能夠訪問(wèn)一個(gè)類的私有部分而又不是該類成員函數(shù)的函數(shù) 稱為該類的友元函數(shù) 友元 為了使用友元函數(shù) 首先應(yīng)該在類的定義中用關(guān)鍵字friend聲明該類的友元函數(shù) 友元函數(shù)除了具有訪問(wèn)指定類的私有成員的特權(quán)之外 其他方面與普通函數(shù)完全一樣 應(yīng)該慎用友元 聲明友元相當(dāng)于在實(shí)現(xiàn)封裝的黑盒子上開(kāi)洞 如果一個(gè)類聲明了很多友元 則相當(dāng)于在黑盒子上開(kāi)了很多個(gè)洞 顯然 這將嚴(yán)重破壞封裝性 參見(jiàn)P110 友元 友元是C 提供的一種破壞數(shù)據(jù)封裝和數(shù)據(jù)隱藏的機(jī)制 通過(guò)將一個(gè)模塊聲明為另一個(gè)模塊的友元 一個(gè)模塊能夠引用到另一個(gè)模塊中本是被隱藏的信息 可以使用友元函數(shù)和友元類 為了確保數(shù)據(jù)的完整性 及數(shù)據(jù)封裝與隱藏的原則 建議盡量不使用或少使用友元 友元函數(shù) 友元函數(shù)是在類定義中由關(guān)鍵字friend修飾說(shuō)明的非成員函數(shù) 在它的函數(shù)體中能夠通過(guò)對(duì)象名訪問(wèn)private和protected成員作用 增加靈活性 使程序員可以在封裝和快速性方面做合理選擇 訪問(wèn)對(duì)象中的成員必須通過(guò)對(duì)象名 友元 友元函數(shù)舉例 include includeclassPoint public Point doublexi doubleyi X xi Y yi doubleGetX returnX doubleGetY returnY frienddoubleDistance Point 友元 doubleDistance Point 友元類 若一個(gè)類為另一個(gè)類的友元 則此類的所有成員都能訪問(wèn)對(duì)方類的私有成員 定義語(yǔ)法 將友元類名在另一個(gè)類中使用friend修飾說(shuō)明 友元 友元類舉例 classA friendclassB public voidDisplay cout x endl private intx classB public voidSet inti voidDisplay private Aa 友元 voidB Set inti a x i voidB Display a Display 友元函數(shù) 友元函數(shù)不是當(dāng)前類中的成員函數(shù) 它可以是一個(gè)普通函數(shù) 也可以是另外一個(gè)類的成員函數(shù) 當(dāng)函數(shù)被聲明為一個(gè)類的友元函數(shù)后 它就可以通過(guò)對(duì)象名訪問(wèn)類的私有成員和保護(hù)成員 普通函數(shù)作為友元函數(shù)普通函數(shù)作為類的友元函數(shù)后 就可以通過(guò)對(duì)象訪問(wèn)封裝在類內(nèi)部的數(shù)據(jù) 可以將友元函數(shù)定義在類的內(nèi)部 也可以定義在類外部 但通常都定義在類外部 friend函數(shù)返回值函數(shù)名 形參表 函數(shù)體 友元函數(shù) 例2 20 使用友元函數(shù)計(jì)算兩個(gè)復(fù)數(shù)的和注意友元函數(shù)不是類的成員函數(shù) 在類外定義時(shí) 不能在函數(shù)名前加 類名 也不能通過(guò)對(duì)象來(lái)引用友元函數(shù) 友元函數(shù)在使用

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論