C講義完整版課件_第1頁
C講義完整版課件_第2頁
C講義完整版課件_第3頁
C講義完整版課件_第4頁
C講義完整版課件_第5頁
已閱讀5頁,還剩263頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、C+語言編程寧 博程序設(shè)計方法的發(fā)展歷程面向過程的程序設(shè)計方法程序的目的:用于數(shù)學計算主要工作:設(shè)計求解問題的過程缺點:對于龐大、復雜的程序難以開發(fā)和維護程序設(shè)計方法的發(fā)展歷程面向過程的結(jié)構(gòu)化程序設(shè)計方法設(shè)計思路自頂向下、逐步求精。采用模塊分解與功能抽象,自頂向下、分而治之程序結(jié)構(gòu)按功能劃分為若干個基本模塊各模塊間的關(guān)系盡可能簡單,功能上相對獨立;每一模塊內(nèi)部均是由順序、選擇和循環(huán)三種基本結(jié)構(gòu)組成其模塊化實現(xiàn)的具體方法是使用子程序程序設(shè)計方法的發(fā)展歷程面向過程的結(jié)構(gòu)化程序設(shè)計方法優(yōu)點 有效地將一個較復雜的程序系統(tǒng)設(shè)計任務(wù)分解成許多易于控制和處理的子任務(wù),便于開發(fā)和維護。程序設(shè)計方法的發(fā)展歷程面

2、向過程的結(jié)構(gòu)化程序設(shè)計方法缺點:可重用性差、數(shù)據(jù)安全性差、難以開發(fā)圖形界面的應(yīng)用把數(shù)據(jù)和處理數(shù)據(jù)的過程相互獨立當數(shù)據(jù)結(jié)構(gòu)改變時,所有相關(guān)的處理過程都要進行相應(yīng)的修改圖形用戶界面的應(yīng)用,很難用過程來描述和實現(xiàn),開發(fā)和維護都很困難面向?qū)ο蟮脑O(shè)計思想面向?qū)ο蟮某绦蛟O(shè)計方法將數(shù)據(jù)及對數(shù)據(jù)的操作方法封裝在一起,作為一個相互依存、不可分離的整體對象。對同類型對象抽象出其共性,形成類。類通過一個簡單的外部接口,與外界發(fā)生關(guān)系基本設(shè)計思想封裝軟件復用面向?qū)ο蟮脑O(shè)計思想面向?qū)ο蟮某绦蛟O(shè)計方法優(yōu)點程序模塊間的關(guān)系更為簡單,程序模塊的獨立性、數(shù)據(jù)的安全性就有了良好的保障。通過繼承與多態(tài)性,可以大大提高程序的可重用性

3、,使得軟件的開發(fā)和維護都更為方便面向?qū)ο蟮幕靖拍?- 對象一般意義上的對象是現(xiàn)實世界中一個實際存在的事物??梢允怯行蔚模ū热缫惠v汽車),也可以是無形的(比如一項計劃)。是構(gòu)成世界的一個獨立單位,具有:靜態(tài)特征:可以用某種數(shù)據(jù)來描述動態(tài)特征:對象所表現(xiàn)的行為或具有的功能面向?qū)ο蟮幕靖拍?- 對象面向?qū)ο蠓椒ㄖ械膶ο笫窍到y(tǒng)用來描述客觀事物的一個實體,它是用來構(gòu)成系統(tǒng)的一個基本單位。對象由一組屬性和一組行為構(gòu)成。屬性:用來描述對象靜態(tài)特征的數(shù)據(jù)項。行為:用來描述對象動態(tài)特征的操作。面向?qū)ο蟮幕靖拍?- 類分類人類通常的思維方法分類所依據(jù)的原則抽象忽略事物的非本質(zhì)特征,只注意那些與當前目標有關(guān)的

4、本質(zhì)特征,從而找出事物的共性,把具有共同性質(zhì)的事物劃分為一類,得出一個抽象的概念。例如,石頭、樹木、汽車、房屋等都是人們在長期的生產(chǎn)和生活實踐中抽象出的概念。面向?qū)ο蟮幕靖拍?- 類面向?qū)ο蠓椒ㄖ械念惥哂邢嗤瑢傩院托袨榈囊唤M對象的集合為屬于該類的全部對象提供了抽象的描述,包括屬性和行為兩個主要部分。類與對象的關(guān)系:猶如模具與鑄件之間的關(guān)系,一個屬于某類的對象稱為該類的一個實例。面向?qū)ο蟮幕靖拍?- 封裝把對象的屬性和行為結(jié)合成一個獨立的系統(tǒng)單位盡可能隱蔽對象的內(nèi)部細節(jié)。對外形成一個邊界(或者說一道屏障),只保留有限的對外接口使之與外部發(fā)生聯(lián)系。面向?qū)ο蟮幕靖拍?- 繼承繼承對于軟件復用有

5、著重要意義,是面向?qū)ο蠹夹g(shù)能夠提高軟件開發(fā)效率的重要原因之一。定義:特殊類的對象擁有其一般類的全部屬性與行為,稱作特殊類對一般類的繼承。例如:將Person作為一個一般類,Student便是一個特殊類。面向?qū)ο蟮幕靖拍?- 多態(tài)性多態(tài)性是指在一般類中定義的屬性或行為,被特殊類繼承之后,可以具有不同的數(shù)據(jù)類型或表現(xiàn)出不同的行為。這使得同一個屬性或行為在一般類及其各個特殊類中具有不同的語義。例如:數(shù)的加法-實數(shù)的加法 -復數(shù)的加法C+語言概述C+語言的產(chǎn)生C+的特點一個簡單的C+程序?qū)嵗鼵+語言的產(chǎn)生C+是從C語言發(fā)展演變而來的,首先是一個更好的C。引入了類的機制,最初的C+被稱為帶類的C。19

6、83年正式取名為C+。C+語言的標準化工作從1989年開始,于1994年制定了ANSI C+標準草案。以后又經(jīng)過不斷完善,成為目前的C+。C+的特點全面兼容C它保持了C的簡潔、高效和接近匯編語言等特點對C的類型系統(tǒng)進行了擴充C+也支持面向過程的程序設(shè)計,不是一個純正的面向?qū)ο蟮恼Z言支持面向?qū)ο蟮姆椒?、對象、繼承、抽象、封裝、.一個簡單的C+程序?qū)嵗?include void main(void) coutHello!n; coutWelcome to c+!n;一個簡單的C+程序?qū)嵗\行結(jié)果:Hello!Welcome to c+!注釋C中的注釋:塊注釋 /* */* This is a c

7、omment */不允許嵌套C+中的注釋C+繼承了C的塊注釋方式增加了一種行注釋方式C+把任何一行中從“/”開始直到該行結(jié)束的所有內(nèi)容皆視為注釋注釋 - 一個簡單的例子#include #include void main() / Checking if a keyword is ESC int i, key; while( 1 ) key = getch(); / Get a key from console if (key = x1B printf(“nEscape! ”); return; else printf(“nKeycode is %2XH”, key); 作用域模塊:在C語言中

8、模塊的概念是指在花括號之間的一組語句作用域的種類局部模塊作用語:變量定義在模塊范圍內(nèi)文件作用域:變量定義在全局范圍內(nèi),只限于當前文件的存??;全局作用域:變量定義在全局范圍內(nèi),對全程序有效。實現(xiàn)方式:include和extern類作用域:變量定義在類中,在類范圍內(nèi)有效作用域: : 運算符: 指明作用域。 例 int x; void f() int x=1; :x=2; return; 作用域 - 一個簡單的例子#include int global = 10;void main() int global = 5; printf(“The value of global is : %dn”, gl

9、obal); return;作用域 - 作用域分辨操作符全局變量訪問:global#include int global = 10;void main() int global = 5; printf(“The value of inner global is : %dn”, global); printf(“The value of outer global is : %dn”, :global); return;指針指針是C語言的一個非常重要的特征實際上是內(nèi)存地址,非常靈活且非常高效但又潛伏著非常大的危險性具有數(shù)據(jù)類型,可以進行指針運算無值型指針,void *,是一種非常有用且十分靈活的指

10、針類型常量指針定義格式 const type * ptr_name; 其含義是指向常量的指針不允許通過指針來修改其指向的對象的值可以修改指針的值例子const int * ptr; const int i=10;ptr = & i; / 修改指針的值*ptr = i+10; / 錯誤操作,試圖修改指針指向的內(nèi)容常量指針例子const char * ptr;const char str10=“hehehe”;ptr = str; / 指針賦值ptr3 = ; / 錯誤操作,試圖修改指針指向的內(nèi)容常量指針const int * ptr;int i=10;ptr = &i; / 指針賦值, 等價于(

11、const int *)&i*ptr = 15; / 錯誤操作,試圖修改指針指向的內(nèi)容i+; cout “i = ” *ptr endl;輸出結(jié)果為:11常量指針不允許將const類型的變量地址賦值給一般的變量指針int * ptr;const int i = 10;ptr = &i; / 編譯錯誤ptr = (int *)&i; / 正確*ptr = *ptr + 1; cout “i = ” *ptr endl;輸出結(jié)果為:11指針常量定義格式 type * const ptr_name; 其含義是指針變量的值不可改變不允許修改指針變量的地址值可以修改指針指向的變量值,如果指向的對象不是一

12、個常量的話例子int * const ptr1;void * const ptr2;指針常量int num=10;int * const const_ptr = #const int * ptr_to_const = #int const * ptr = #const_ptr =(int * const) & num; / 編譯錯誤 /試圖修改一個指針常量的地址值*ptr = num; / 編譯錯誤 /試圖修改常量指針指向的對象值void類型1.說明函數(shù)沒有返回值; void fun(void) return ;2.表示函數(shù)不需要任何入口參數(shù); double fun(v

13、oid) 3.可將指針說明為void型。這種指針可被賦以其它任何類型的指針。 double a=9.0; double *pd=&a; void *p; p=pd; 練習用指針寫一個swap函數(shù),交換兩個整數(shù) a和b的值。打印交換前后a,b的值。引用先看一個簡單的例子int i, &j=i;i=1;cout“i=” iendl; / output: i=1j+;cout“i=” iendl; / output: i=2i+;cout“j=” jendl; / output: j=3引用引用的定義格式type & ref_name = var_name;引用定義說明引用必須在定義時進行初始化被引

14、用的變量必須在引用定義之前定義引用一經(jīng)定義,便無法重新引用其它變量引用對引用概念的理解int i=10, &j=i;在物理存儲中,變量i有存儲單元,但引用j沒有存儲單元,其具體表現(xiàn)是變量i和引用j的物理地址是相同的內(nèi)存單元 0XEFFF21 有兩個名字,可以將引用j理解為變量i的別名在同一個模塊中的引用沒有太大意義,但在函數(shù)調(diào)用時可以實現(xiàn)傳名調(diào)用10變量i引用j0XEFFF21練習用引用寫一個swap函數(shù),交換兩個整數(shù) a和b的值。打印交換前后a,b的值。C+的內(nèi)存格局全局數(shù)據(jù)區(qū)(data area)代碼區(qū)(code area)棧區(qū)(stack area)堆區(qū)(heap area)C+的內(nèi)存格

15、局全局變量、靜態(tài)數(shù)據(jù)、常量存放在全局數(shù)據(jù)區(qū);所有類成員函數(shù)和非成員函數(shù)代碼存放在代碼區(qū);為運行函數(shù)而分配的局部變量、函數(shù)參數(shù)、返回數(shù)據(jù)、返回地址等存放在棧區(qū);其余的空間都被稱為堆區(qū)。堆內(nèi)存的分配與釋放當程序運行到需要一個動態(tài)分配的變量或?qū)ο髸r,必須向系統(tǒng)申請取得堆中的一塊所需大小的存貯空間,用于存貯該變量或?qū)ο?。當不再使用該變量或?qū)ο髸r,也就是它的生命結(jié)束時,要顯式釋放它所占用的存貯空間,這樣系統(tǒng)就能對該堆空間進行再次分配,做到重復使用有限的資源。在C+中,申請和釋放堆中分配的存貯空間,分別使用new和delete的兩個運算符來完成,其使用的格式如下:指針變量名=new 類型名(初始化式);d

16、elete 指針名;new運算符返回的是一個指向所分配類型變量(對象)的指針。對所創(chuàng)建的變量或?qū)ο?,都是通過該指針來間接操作的,而動態(tài)創(chuàng)建的對象本身沒有名字。 堆內(nèi)存的分配與釋放C中的malloc和free函數(shù)在C+中可以用alloc.h頭文件中聲明void * malloc(size_t size); void free(void *);堆內(nèi)存的分配與釋放if (array=(int*)malloc(arraysize*sizeof(int)=NULL)cout“cant allocate more memory.n”;exit(1);free(array);堆內(nèi)存的分配與釋放newnew

17、類型名T(初值列表)功能:在程序執(zhí)行期間,申請用于存放T類型對象的內(nèi)存空間,并依據(jù)初值列表調(diào)用合適的構(gòu)造函數(shù)。結(jié)果值:成功:T類型的指針,指向新分配的內(nèi)存。失?。?(NULL)堆內(nèi)存的分配與釋放deletedelete 指針P功能:釋放指針P所指向的內(nèi)存。P必須是new操作的返回值。堆內(nèi)存的分配與釋放用初始化式(initializer)來顯式初始化 例如:int *pi=new int(0);當pi生命周期結(jié)束時,必須釋放pi所指向的目標: delete pi;注意這時釋放了pi所指的目標的內(nèi)存空間,也就是撤銷了該目標,稱動態(tài)內(nèi)存釋放(dynamic memory deallocation),

18、但指針pi本身并沒有撤銷,它自己仍然存在,該指針所占內(nèi)存空間并未釋放。 堆i用初始化式(initializer)來顯式初始化 例如:int *pi=new int(0);當pi生命周期結(jié)束時,必須釋放pi所指向的目標: delete pi;注意這時釋放了pi所指的目標的內(nèi)存空間,也就是撤銷了該目標,稱動態(tài)內(nèi)存釋放(dynamic memory deallocation),但指針pi本身并沒有撤銷,它自己仍然存在,該指針所占內(nèi)存空間并未釋放。 堆內(nèi)存的分配與釋放堆i堆內(nèi)存的分配與釋放對于數(shù)組進行動態(tài)分配的格式為:指針變量名=new 類型名下標表達式;delete 指向該數(shù)組的指針變量名;堆內(nèi)存的

19、分配與釋放if (array=new int arraysize)=NULL)cout“cant allocate more memory.n”;exit(1);delete array; 堆內(nèi)存的分配與釋放【例】動態(tài)數(shù)組的建立與撤銷#include #include void main()int n;char *pc;cout請輸入動態(tài)數(shù)組的元素個數(shù)n;pc=new charn; /strcpy(pc,堆內(nèi)存的動態(tài)分配);coutpcendl;delete pc; / 撤銷并釋放pc所指向的n個字符的內(nèi)存空間return ;堆內(nèi)存的分配與釋放動態(tài)分配的三個特點:首先,變量n在編譯時沒有確定的

20、值,而是在運行中輸入,按運行時所需分配堆空間,這一點是動態(tài)分配的優(yōu)點,可克服數(shù)組“大開小用”的弊端。delete pc是將n個字符的空間釋放,而用delete pc則只釋放了一個字符的空間;其次如果有一個char *pc1,令pc1=p,同樣可用delete pc1來釋放該空間。盡管C+不對數(shù)組作邊界檢查,但在堆空間分配時,對數(shù)組分配空間大小是紀錄在案的。第三,沒有初始化式(initializer),不可對數(shù)組初始化。 堆內(nèi)存的分配與釋放指針使用的幾個問題:動態(tài)分配失敗。返回一個空指針(NULL),表示發(fā)生了異常,堆資源不足,分配失敗。指針刪除與堆空間釋放。刪除一個指針p(delete p;)

21、實際意思是刪除了p所指的目標(變量或?qū)ο蟮龋?,釋放了它所占的堆空間,而不是刪除本身,釋放堆空間后,成了空懸指針 堆內(nèi)存的分配與釋放內(nèi)存泄漏(memory leak)和重復釋放。new與delete 是配對使用的, delete只能釋放堆空間。如果new返回的指針值丟失,則所分配的堆空間無法回收,稱內(nèi)存泄漏,同一空間重復釋放也是危險的,所以必須妥善保存new返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會重復釋放堆內(nèi)存空間。動態(tài)分配的變量或?qū)ο蟮纳?。無名對象,它的生命期并不依賴于建立它的作用域,比如在函數(shù)中建立的動態(tài)對象在函數(shù)返回后仍可使用。我們也稱堆空間為自由空間(free store)就

22、是這個原因。 練習建立動態(tài)整型數(shù)組用戶輸入數(shù)組長度,并且用戶輸入初始化數(shù)組,求和并打印到屏幕。練習編寫程序。測試堆內(nèi)存的容量:每次申請一個數(shù)組,內(nèi)含100個整數(shù),直到分配失敗,并打印堆容量。面向?qū)ο缶幊傻幕咎攸c抽象封裝繼承多態(tài)性面向?qū)ο缶幊傻幕咎攸c -抽象抽象是對具體對象(問題)進行概括,抽出這一類對象的公共性質(zhì)并加以描述的過程。只注意問題的本質(zhì)及描述,而忽略實現(xiàn)過程或細節(jié)。數(shù)據(jù)抽象:描述某類對象的屬性或狀態(tài)(對象相互區(qū)別的物理量)。代碼抽象:描述某類對象的共有的行為特征或具有的功能。抽象的實現(xiàn):通過類定義中的public來實現(xiàn)。抽象出來的數(shù)據(jù)和行為對外是可見的面向?qū)ο缶幊傻幕咎?- 抽

23、象class Watch public: void SetTime(int NewH, int NewM, int NewS); void ShowTime(); private: int Hour,Minute,Second;抽象的行為面向?qū)ο缶幊傻幕咎攸c -封裝將實現(xiàn)細節(jié)涉及到的數(shù)據(jù)成員、實現(xiàn)代碼封裝在類中,對外是不可見的。目的是曾強安全性和簡化編程,使用者不必了解具體的實現(xiàn)細節(jié),而只需要通過外部接口,以特定的訪問權(quán)限,來使用類的成員實現(xiàn)封裝:通過類定義中的private來實現(xiàn)面向?qū)ο缶幊傻幕咎攸c -封裝class Watch public: void SetTime(int NewH

24、, int NewM, int NewS); void ShowTime(); private: int Hour,Minute,Second;封裝的數(shù)據(jù)成員面向?qū)ο缶幊傻幕咎攸c -繼承繼承是C+中支持層次分類的一種機制,允許程序員在保持原有類特性的基礎(chǔ)上,進行更具體的類定義,形成一個類層次關(guān)系繼承的主要目的和作用代碼復用提高程序設(shè)計語言的建模能力接近現(xiàn)實世界的實際模型,也就是模型表達能加自然,這樣使得建?,F(xiàn)實世界更加容易具體的內(nèi)容將在后面的章節(jié)中介紹面向?qū)ο缶幊傻幕咎攸c -多態(tài)性多態(tài)的概念:同一名稱,不同的功能實現(xiàn)方式。目的:達到行為標識統(tǒng)一,減少程序中標識符的個數(shù)。類的概念和定義類的概

25、念類是用來描述一組對象的相同屬性和行為,它為屬于該類的全部對象提供了統(tǒng)一的抽象描述包括抽象屬性和抽象行為利用類可以實現(xiàn)細節(jié)進行封裝包括用于實現(xiàn)的成員數(shù)據(jù)和成員函數(shù)利用類易于編寫大型復雜程序,其模塊化程度比C中采用函數(shù)更高類的概念和定義類的定義class 類名稱 public: 公有成員(外部接口) private: 私有成員 (實現(xiàn)細節(jié)) protected: 保護型成員 (用于類層次的訪問控制)類是一種用戶自定義的類型類的概念和定義class Watch public: void SetTime(int NewH, int NewM, int NewS); void ShowTime();

26、private: int Hour, Minute, Second;成員數(shù)據(jù)成員函數(shù)類的概念和定義void Watch : SetTime(int NewH, int NewM, int NewS) Hour=NewH; Minute=NewM; Second=NewS;void Watch : ShowTime() coutHour:Minute:Second;類的概念和定義成員數(shù)據(jù)與一般的變量定義相同,但需要將它放在類的定義體中成員函數(shù)在類中說明原形,在類外定義函數(shù)體實現(xiàn),并在函數(shù)名前使用類名加以限定。也可以直接在類中定義函數(shù)體,形成內(nèi)聯(lián)成員函數(shù)。在類的定義外部實現(xiàn)內(nèi)聯(lián)成員函數(shù)時一定要顯式

27、加上inline關(guān)鍵詞允許定義重載函數(shù)和帶缺省形參值的函數(shù)類的概念和定義內(nèi)聯(lián)成員函數(shù)為了提高運行時的效率,對于較簡單的函數(shù)可以聲明為內(nèi)聯(lián)形式。實現(xiàn)內(nèi)聯(lián)成員函數(shù)的方式:將函數(shù)體放在類的定義中。在外部實現(xiàn)中顯式使用inline關(guān)鍵字。類的概念和定義內(nèi)聯(lián)成員函數(shù)的內(nèi)部實現(xiàn)class Location public: void Init(int initX, int initY) X=initX; Y=initY; int GetX() return X; int GetY() return Y; private: int X,Y;內(nèi)聯(lián)成員函數(shù)類的概念和定義內(nèi)聯(lián)成員函數(shù)的外部實現(xiàn)class Locat

28、ion public: void Init(int initX, int initY); int GetX(); int GetY(); private: int X,Y;類的概念和定義內(nèi)聯(lián)成員函數(shù)的外部實現(xiàn)inline void Location: Init(int initX,int initY) X=initX; Y=initY;inline int Location:GetX() return X; inline int Location:GetY() return Y; 類的概念和定義私有成員 (私有數(shù)據(jù)成員和私有成員函數(shù))在關(guān)鍵字private后面聲明,只允許本類中的函數(shù)訪問,而類

29、外部的任何函數(shù)都不能訪問。如果緊跟在類名稱的后面聲明私有成員,則關(guān)鍵字private可以省略。類的概念和定義私有成員class Watch private: int Hour,Minute,Second; public: void SetTime(int NewH, int NewM, int NewS); void ShowTime();private可以缺省類的概念和定義私有成員class Watch w;int i;i=w.Hour; / 編譯錯誤,試圖訪問私有成員數(shù)據(jù)w.SetTime(); / 正確,因為SetTime是公有成員函數(shù)類的概念和定義公有成員(公有數(shù)據(jù)成員和公有成員函數(shù))

30、在關(guān)鍵字public后面聲明,它們是類與外部的接口,任何外部函數(shù)都可以訪問公有類型數(shù)據(jù)和函數(shù)。類的概念和定義公有成員class Watch public: int Hour,Minute,Second; void SetTime(int NewH, int NewM, int NewS); void ShowTime();類的概念和定義公有成員class Watch w;int i;i=w.Hour; /正確,因為Hour是公有成員數(shù)據(jù)w.SetTime(); / 正確,因為SetTime是公有成員函數(shù)類的概念和定義保護成員(保護數(shù)據(jù)成員和保護成員函數(shù))與private類似,在類的外部函數(shù)中不

31、能訪問類中的保護成員在類的子類中可能可以訪問該類的保護成員,這取決于訪問控制,在后面講述類的概念和定義不能試圖給類定義中的數(shù)據(jù)成員進行初始化類僅僅是類型的說明,而對象的數(shù)據(jù)成員的初始化必須有構(gòu)造函數(shù)來完成class Watch private: int Hour = 0, Minute = 0, Second = 0; public: void SetTime(int NewH, int NewM, int NewS); void ShowTime();錯誤!C+中的結(jié)構(gòu)C+中的結(jié)構(gòu)比C語言中的結(jié)構(gòu)具有更加強大的功能在C+中結(jié)構(gòu)和類具有類似的功能在結(jié)構(gòu)中可以定義成員函數(shù)、可以進行繼承;可以象C

32、+的類一樣實現(xiàn);所有的解釋與類相同,除了只是缺省的訪問控制是public,而類的缺省訪問控制是private結(jié)構(gòu)是C+擴展C的第一步,但不推薦這種結(jié)構(gòu)編程方式C+中的結(jié)構(gòu)Struct Person int age; int getAge() return age; ;Struct Student : Person int sno; int getSno() return sno; ;對象類的對象是該類的某一特定實體,即類類型的變量。定義形式: 類名 對象名;例: watch myWatch;當然也可以有對象的指針,對象的引用等對象類中成員的訪問方式類中的成員函數(shù)訪問類中的成員數(shù)據(jù)直接使用成員名

33、類外訪問使用“對象名.成員名”方式訪問 public 屬性的成員對象類中成員的訪問方式#includeclass Watch ./類的定義略/.類的實現(xiàn)略void main(void) Watch myWatch; myWatch.SetTime(8,30,30); myWatch.ShowTime();構(gòu)造函數(shù)構(gòu)造函數(shù)的作用是在對象被創(chuàng)建時使用特定的值構(gòu)造對象,或者說將對象初始化為一個特定的狀態(tài)。在對象創(chuàng)建時由系統(tǒng)自動調(diào)用。如果程序中未定義出,則系統(tǒng)自動產(chǎn)生出一個缺省形式的構(gòu)造函數(shù) - 缺省構(gòu)造函數(shù)允許為內(nèi)聯(lián)構(gòu)造函數(shù)、重載構(gòu)造函數(shù)、帶缺省形參值的構(gòu)造函數(shù)構(gòu)造函數(shù)定義說明構(gòu)造函數(shù)名與所在的類名

34、相同;構(gòu)造函數(shù)沒有返回類型,因此在定義構(gòu)造函數(shù)時不能帶有任何帶有返回值的返回語句;不能將構(gòu)造函數(shù)說明為void類型;可以有返回語句 return;構(gòu)造函數(shù)只能用于構(gòu)造類的實例對象,它的調(diào)用是隱含的,不能對任何已經(jīng)構(gòu)造的對象再次進行構(gòu)造函數(shù)的顯式調(diào)用;構(gòu)造函數(shù)定義說明構(gòu)造函數(shù)一般總是被定義為公有成員,否則在外部定義類對象時無法對其進行初始化構(gòu)造函數(shù)的定義與普通成員函數(shù)一樣,可以在類定義體內(nèi)部,也可以放在類定義體的外部,且可以直接訪問其類所在的所有其他成員,包括成員數(shù)據(jù)和成員函數(shù)構(gòu)造函數(shù)定義說明class Person int age;Person() age=0;class Student :p

35、ublic Person int stno; Person p; / 編譯錯誤必須將該構(gòu)造函數(shù)變?yōu)楣谐蓡T構(gòu)造函數(shù)一個類可以有多個構(gòu)造函數(shù),和普通函數(shù)一樣,同名的構(gòu)造函數(shù)相互重載Class d_String Public: d_String(); d_String(const d_String *); d_String(const char *); ;構(gòu)造函數(shù)對象的初始化d_String str1; / 調(diào)用缺省構(gòu)造函數(shù)d_String str1(); / 調(diào)用缺省構(gòu)造函數(shù)d_String str1(“Bing Wang”); / 調(diào)用構(gòu)造函數(shù)d_String str1=d_String();

36、 / 調(diào)用缺省構(gòu)造函數(shù)d_String str1=d_String(“Bing Wang”); / 調(diào)用構(gòu)造函數(shù)構(gòu)造函數(shù)構(gòu)造函數(shù)一般用來對對象的成員數(shù)據(jù)進行初始化當類的成員數(shù)據(jù)比較多時這種初始化語句比較多Class Account public: Account() _name = 0; _balance = 0.0; _acct_nmbr = 0; ;構(gòu)造函數(shù) Account(const char * name, double balance, int acct_nmbr) _name = new char strlen(name)+1 ; strcpy(_name, name); _bal

37、ance = balance; _acct_nmbr = acct_nmbr; ;.;構(gòu)造函數(shù)成員初始化表Class Account public: Account() : _name ( 0), _balance (0.0), _acct_nmbr (0) ; Account(const char * name, double balance, int acct_nmbr) : balance = balance, _acct_nmbr = acct_nmbr; _name = new char strlen(name)+1 ; strcpy(_name, name); ;.;初始化列表的效

38、率比賦值語句的效率要高成員初始化表構(gòu)造函數(shù)const成員函數(shù)一個類中的成員函數(shù)可以是constclass d_Set public: d_Set(); unsigned long cardinality() const; d_Boolean is_empty() const; const成員函數(shù)const成員函數(shù)含義是該函數(shù)只能讀取該類中的成員數(shù)據(jù),而不能修改,因此該成員函數(shù)不能修改所在類的成員數(shù)據(jù)該成員函數(shù)不能調(diào)用所在類中的非const成員函數(shù)根據(jù)const成員函數(shù)的定義不能將構(gòu)造函數(shù)定義為const類型,因為它要初始化成員數(shù)據(jù)的值const關(guān)鍵字可以被用于參與對重載函數(shù)的區(qū)分const是函

39、數(shù)類型的一個組成部分,因此在實現(xiàn)部分也要帶const關(guān)鍵字。const對象const對象與其他類型的const對象一樣const對象調(diào)用構(gòu)造函數(shù)初始化對象后不能再被修改 const d_String str1 = “Bing Wang”; . str1 = “Bing Wang”; /錯誤 通常,const對象只能調(diào)用const成員函數(shù) 舉例#includeclass R public: R(int r1, int r2)R1=r1;R2=r2; void print(); void print() const; private: int R1,R2;舉例void R:print() cout

40、R1:R2endl;void R:print() const coutR1;R2endl;void main() R a(5,4); a.print(); /調(diào)用void print() const R b(20,52); b.print(); /調(diào)用void print() const隱含的this指針來看一個例子Class ArrayX Private : int dim; double * x;Public : ArrayX(int d); ArrayX(); void WriteX( int n, double val); double ReadX(int n); void Print

41、X( int n ); void PrintAll( void );隱含的this指針問題:成員函數(shù),例如ReadX,是如何知道當前對象的地址的呢?因為只有通過地址才能操作該對象中的數(shù)據(jù)成員;這正好是this指針的作用為了解決上述問題,實際上在成員函數(shù)參數(shù)表中存在一個額外的參數(shù):WriteX(Array * this, double val);ReadX(ArrayX * this, int n);PrintX(ArrayX * this, int n);PrintAll(ArrayX * this);隱含的this指針這個ArrayX * this指針是隱含的,由他的調(diào)用這提供,指向被操作的

42、對象在成員函數(shù)內(nèi)部也可以使用this指針,例如Void Write(int n, double val) if (a dim) this-xn = val;上述程序中this指針可缺省Void Write(int n, double val) if (a dim) xn = val;隱含的this指針This指針除了上述用法之外,可以使用在返回值中class Screen Public: Screen(); Screen & set( char ); Screen & move( int, int ); Screen & clear(); Screen & display();Private:

43、 ./ 數(shù)據(jù)成員說明; 隱含的this指針This指針除了上述用法之外,可以使用在返回值中Screen & Screen:clear( char bg) _cursor = 0; _screen.assign(_screen.size(), bg); return *this;myScreen.clear().move(2,2).set(*).display();缺省構(gòu)造函數(shù)缺省構(gòu)造函數(shù)是指沒有參數(shù)的構(gòu)造函數(shù)當類的定義中沒有定義構(gòu)造函數(shù)時,系統(tǒng)會為該類生成一個缺省構(gòu)造函數(shù),在進行對象說明時系統(tǒng)會調(diào)用系統(tǒng)生成的缺省構(gòu)造函數(shù)系統(tǒng)生成的缺省構(gòu)造函數(shù)不做任何事情當類中用戶定義了構(gòu)造函數(shù)后,編譯器就會忽

44、略系統(tǒng)生成的缺省構(gòu)造函數(shù),即使你沒有定義缺省構(gòu)造函數(shù)建議用戶定義自己的缺省構(gòu)造函數(shù),因為系統(tǒng)生成的缺省構(gòu)造函數(shù)不做任何事情缺省構(gòu)造函數(shù)Class d_String Public: d_String(); / 缺省構(gòu)造函數(shù) d_String(const d_String *); d_String(const char *); ;d_String str; / 調(diào)用用戶定義的缺省構(gòu)造函數(shù)缺省構(gòu)造函數(shù)Class d_String Public: /d_String(); / 缺省構(gòu)造函數(shù) /d_String(const d_String *); /d_String(const char *); /

45、沒有其它構(gòu)造函數(shù)定義;d_String str; / 調(diào)用系統(tǒng)生成的缺省構(gòu)造函數(shù)缺省構(gòu)造函數(shù)Class d_String Public: /d_String(); / 缺省構(gòu)造函數(shù) d_String(const d_String *); d_String(const char *); ;d_String str; / 編譯錯誤,因為編譯器忽略系 / 統(tǒng)生成的缺省構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),其形參為本類的對象引用class 類名 public : 類名(形參);/構(gòu)造函數(shù) 類名(類名 &對象名);/拷貝構(gòu)造函數(shù) .;類名: 類名(類名 &對象名)/拷貝構(gòu)造函數(shù)的實現(xiàn) 函

46、數(shù)體 拷貝構(gòu)造函數(shù)class Location public: Location(int xx=0,int yy=0)X=xx; Y=yy; Location(Location & p); int GetX() return X; int GetY() return Y; private: int X,Y;拷貝構(gòu)造函數(shù)如果沒有定義類的拷貝構(gòu)造函數(shù),系統(tǒng)就會自動生成一個默認的拷貝構(gòu)造函數(shù),其功能是把初始值對象的每個數(shù)據(jù)成員的值都復制到新建立的對象中何時調(diào)用拷貝構(gòu)造函數(shù)Location L1;Location L2(L1); / 調(diào)用拷貝構(gòu)造函數(shù)Location L3 = L1; / 調(diào)用拷貝構(gòu)造

47、函數(shù)F( L1 ); / 調(diào)用拷貝構(gòu)造函數(shù)L1 = g(); /調(diào)用拷貝構(gòu)造函數(shù), 為被返回 / 的對象建立一個臨時對象拷貝構(gòu)造函數(shù)課堂提問既然系統(tǒng)能夠自動生成一個默認的拷貝構(gòu)造函數(shù),那么用戶是否還有必要生成自己的拷貝構(gòu)造函數(shù)呢?理由是什么?淺拷貝與深拷貝淺拷貝 - 通過一個例子來理解淺拷貝的概念C語言的例子char * p1, *p2;p1 = malloc( 20 );strcpy(p1, “Bin Wang”);p2 = p1;Bin Wang指針p1指針p2淺拷貝與深拷貝淺拷貝 - 通過一個例子來理解淺拷貝的概念C+的例子Class String String(); String(co

48、nst char *) String();private: char * str;String:String() str = 0; String:String() if (str!=0) delete str; String:String(const char * s) str = new char strlen(s)+1; strcpy(str, s); String * s1 = new String(“Bin Wang”); /String * s2 = new String (s1); / 調(diào)用缺省拷貝構(gòu)造函數(shù)淺拷貝與深拷貝淺拷貝 - 通過一個例子來理解淺拷貝的概念淺拷貝的缺點當一個指

49、針指向同一個對象或內(nèi)存單元時存在潛在的錯誤源泉,例如當對象s1被析構(gòu)以后,對象s2無法析構(gòu)是由于缺省拷貝構(gòu)造函數(shù)引起的,必須重寫strstrBin Wangs1s2淺拷貝與深拷貝深拷貝Class String String(); String(const char *); String(String &); String();private: char * str;String:String() str = 0; String:String() if (str!=0) delete str; String:String(const char * s) str = new char strlen

50、(s)+1; strcpy(str, s); String:String(String & s) str = new char strlen(s.str)+1; strcpy(str, s.str); String * s1 = new String( “Bin Wang”); String * s2 = new String( s1 ); 淺拷貝與深拷貝深拷貝深拷貝可以很好地避免指針懸掛問題strstrBin Wangs1s2Bin Wang析構(gòu)函數(shù)完成對象被刪除前的一些清理工作。在對象的生存期結(jié)束的時刻系統(tǒng)自動調(diào)用它,然后再釋放此對象所屬的空間。如果程序中未定義析構(gòu)函數(shù),編譯器將自動產(chǎn)生一

51、個缺省的析構(gòu)函數(shù)。與構(gòu)造函數(shù)一樣,析構(gòu)函數(shù)一般總是被說明為類的一個公有函數(shù)成員,由加上函數(shù)名稱構(gòu)成,沒有返回值,且沒有任何參數(shù)析構(gòu)函數(shù)當一個對象中沒有涉及動態(tài)內(nèi)存分配時,可以使用系統(tǒng)生成的缺省析構(gòu)函數(shù)。如果涉及到動態(tài)內(nèi)存問題時,應(yīng)該編寫自己的顯式析構(gòu)函數(shù);否則存在內(nèi)存泄漏問題當然也可能存在需要處理的情況:在對象的生命周期內(nèi)動態(tài)獲得的各種資源,在析構(gòu)函數(shù)中應(yīng)該需要處理;例如該對象獲得的互斥鎖,在析構(gòu)函數(shù)中應(yīng)該釋放該鎖;析構(gòu)函數(shù)Class Account Public: Account(); Account ( const char *, double = 0.0 ); Account ( con

52、st Account & ); Account();Private: char *_name; unsigned int _acct_nmbr; double _balance;inlineAccount:account() delete _name;例1(1) Account global( “James Joyce” );(2) int main() (3) Account local ( Anna Livia Plurabelle”, 10000 );(4) Account & loc_ref = global;(5) Account * pact = 0;(6) Account loc

53、al_two ( “stephen hero” );(7) pact = new Account( “Stephen Dedalus” );(8) (9) delete pact;(10) 例1該例子中調(diào)用了4次構(gòu)造函數(shù);對應(yīng)地,程序也要調(diào)用4次析構(gòu)函數(shù);類的應(yīng)用舉例一圓型游泳池如圖所示,現(xiàn)在需在其周圍建一圓型過道,并在其四周圍上柵欄。柵欄價格為35元/米,過道造價為20元/平方米。過道寬度為3米,游泳池半徑由鍵盤輸入。要求編程計算并輸出過道和柵欄的造價。游泳池過道類的應(yīng)用舉例#include const float PI = 3.14159;const float FencePrice =

54、35.0;const float ConcretePrice = 20.0;/定義類Circle 及其數(shù)據(jù)和方法class Circle private: float radius; public: Circle(float r); /構(gòu)造函數(shù) float Circumference() const; /圓周長 float Area() const; /圓面積;類的應(yīng)用舉例/ 類的實現(xiàn)/ 構(gòu)造函數(shù)初始化數(shù)據(jù)成員radiusCircle:Circle(float r): radius(r) / 計算圓的周長float Circle:Circumference() const return 2 *

55、 PI * radius; / 計算圓的面積 float Circle:Area() const return PI * radius * radius;類的應(yīng)用舉例void main () float radius; float FenceCost, ConcreteCost; / 提示用戶輸入半徑 cout radius; / 定義 Circle 對象 Circle Pool(radius); Circle PoolRim(radius + 3);類的應(yīng)用舉例/ 計算柵欄造價并輸出 FenceCost = PoolRim.Circumference() * FencePrice; cout

56、 Fencing Cost is $ FenceCost endl; / 計算過道造價并輸出 ConcreteCost = (PoolRim.Area() - Pool.Area()*ConcretePrice; cout Concrete Cost is $ ConcreteCost endl;類的應(yīng)用舉例運行結(jié)果Enter the radius of the pool: 40Fencing Cost is $945.598Concrete Cost is $391.119課堂練習用類實現(xiàn)計數(shù)器抽象數(shù)據(jù)類型class CCounter public: CCounter(); void Up(

57、); void Down(); void Zero(); void Value(); private: int a; ;課堂練習設(shè)計一個棧類型,考慮下面的數(shù)據(jù)結(jié)構(gòu)const int STACK_SIZE=20;class CStack public:CStack();CStack(int sz);CStack();void push(int e);int pop();private:int *item;int sp;int size;課堂練習private:int *item;int sp;int size;CPoint類聲明一個CPoint類來描述點對象。 /point.h class CP

58、oint public:CPoint (int x, int y);int XCoord(); int YCoord(); void Move(int xOffset, int yOffset); private: int X,Y; CPoint: TPoint(int x,int y) X=x; Y=y; int CPoint: XCoord() return X; int CPoint: YCoord() return Y; void CPoint: Move(int xOffset, int yOffset) X+= xOffset;Y+=yOffset; void main(void)

59、 CPoint p(3,4); p.Move(10,20); cout(p.XCoord(), p.XCoord()endl;類的靜態(tài)成員在C語言中有靜態(tài)變量的概念局部靜態(tài)變量 - ,相當于一個局部范圍內(nèi)能夠使用的全局變量對應(yīng)地,在C+中也有靜態(tài)成員的概念靜態(tài)數(shù)據(jù)成員靜態(tài)成員函數(shù)靜態(tài)數(shù)據(jù)成員用關(guān)鍵字static聲明該類的所有對象維護該成員的同一個拷貝Class Score char student20; int language; int maths; int history;Public: static int passmark; static int passnum; Score(); S

60、core();靜態(tài)數(shù)據(jù)成員必須在類外定義和初始化,用(:)來指明所屬的類int Score:passmark = 60;Int Score:passnum = 0;上述定義和初始化必須放在main()函數(shù)的外面來進行,象全局變量一樣int Score:passmark = 60;Int Score:passnum = 0;void main() . Void main() int Score:passmark = 60; int Score:passnum = 0;Static int Score:passmark = 60;Static int Score:passnum = 0;void

溫馨提示

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

最新文檔

評論

0/150

提交評論