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

下載本文檔

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

文檔簡介

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

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論