面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)詳解_第1頁
面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)詳解_第2頁
面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)詳解_第3頁
面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)詳解_第4頁
面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)詳解_第5頁
已閱讀5頁,還剩56頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)詳解演示文稿第1頁,共61頁。優(yōu)選面向?qū)ο蟪绦蛟O計之多態(tài)性與虛函數(shù)第2頁,共61頁。寫出程序運行結(jié)果#include #include Using namespace std;class studentpublic: student (int n,string nam, float s) num= n; name= nam; score= s; void display( ) cout“num:”num “name:”name “score:”scoreendl; protected: int num; string name; float score;clas

2、s graduate : public studentpublic: graduate (int n, string nam, float s, float p): student (n,nam,s), pay(p) void display( ) cout“num:”num “name:”name “score:”score “pay:”paydisplay( ); pt = &g1; pt-display( ); 第3頁,共61頁。6.1 多態(tài)性的概念我們其實已經(jīng)接觸過多態(tài)性的現(xiàn)象。如函數(shù)的重載多態(tài)性分類:從系統(tǒng)實現(xiàn)的角度看,多態(tài)性分為以下兩類:靜態(tài)多態(tài)性:又稱編譯時的多態(tài)性。如函數(shù)重載屬

3、于靜態(tài)多態(tài)性。動態(tài)多態(tài)性:有稱為運行時的多態(tài)性。它主要表現(xiàn)為虛函數(shù)( virtual function )。第4頁,共61頁。6.3 虛函數(shù)能否用一個調(diào)用形式,既能調(diào)用派生類的函數(shù),又能調(diào)用基類同名函數(shù)?C+中的虛函數(shù)就是用來解決這一問題。虛函數(shù)的作用:虛函數(shù)的作用是允許在派生類中重新定義與基類同名的函數(shù),并且可以通過基類指針或引用來訪問基類和派生類中的同名函數(shù)。第5頁,共61頁。6.3 虛函數(shù)#include #include class studentpublic: student (int n,string nam, float s) num= n; name= nam; score=

4、s; void display( ) cout“num:”num “name:”name “score:”scoreendl; protected: int num; string name; float score;class graduate : public studentpublic: graduate (int n, string nam, float s, float p): student (n,nam,s), pay(p) void display( ) cout“num:”num “name:”name “score:”score “pay:”paydisplay( ); /

5、 指向基類對象s1 pt = &g1; pt-display( ); / 指向派生類對象g1,僅輸出了派生類的基類數(shù)據(jù)成員,因為它調(diào)用的是基類成員函數(shù)display! 假如想輸出派生類的全部數(shù)據(jù),當然可以采用下面兩種方法之一:通過派生類對象名g1,調(diào)用派生類對象的成員函數(shù):g1.display( );定義一個指向派生類的指針ptr,并指向g1,然后用ptr-display( )。第6頁,共61頁。6.3 虛函數(shù) 我們可以用虛函數(shù)可以順利解決這一問題。方法是:在基類student 中聲明 display函數(shù)時,在最左邊加上一個關鍵字virtual :virtual void display( )

6、; 就可以student類的display函數(shù)聲明為虛函數(shù),程序其它部分不變編譯運行后,可見,使用pt-display( ),的確將graduate類對象 g1 的全部數(shù)據(jù)顯示了出來,說明它調(diào)用的是g1 的成員函數(shù) display。在派生類中重新定義該函數(shù),要求函數(shù)名、函數(shù)類型、參數(shù)表完全相同。但不加virtual關鍵字。只在類里的成員函數(shù)聲明時,加上關鍵字virtual,在類外定義定義虛函數(shù)時,不加virtual關鍵字。定義一個指向基類對象的指針,并使她指向同一類中的某一對象;通過該指針標量調(diào)用此虛函數(shù),此時調(diào)用的就是指針變量指向的對象的同名函數(shù),而不是基類的同名函數(shù)!第7頁,共61頁。6.

7、3 虛函數(shù)通過使用虛函數(shù)和指針,就能方便地調(diào)用同一類族中不同類對象的同名函數(shù),只要先用基類指針指向該對象即可。#include #include class studentpublic: student (int n,string nam, float s) num= n; name= nam; score= s; virtual void display( ) cout“num:”num “name:”name “score:”scoreendl; protected: int num; string name; float score;class graduate : public stu

8、dentpublic: graduate (int n, string nam, float s, float p): student (n,nam,s), pay(p) void display( ) cout“num:”num “name:”name “score:”score “pay:”paydisplay( ); / 指向基類對象s1 pt = &g1; pt-display( ); / 指向派生類對象g1,調(diào)用g1的顯示函數(shù)display,打印出g1全部數(shù)據(jù)成員第8頁,共61頁。6.3 虛函數(shù)將函數(shù)重載與虛函數(shù)比較,可見:函數(shù)重載是解決的是同一層次上的同名函數(shù)的問題。是橫向重載。虛

9、函數(shù)解決的是不同派生層次上的同名函數(shù)的問題。相當于縱向重載。同一類族的虛函數(shù)的首部是相同的;而重載函數(shù)的首部不相同(參數(shù)表不能相同)。第9頁,共61頁。6.3 虛函數(shù)靜態(tài)關聯(lián)與動態(tài)關聯(lián)C+在編譯或運行時,對多個同名函數(shù)究竟調(diào)用哪一個函數(shù),需要一定的機制來確定。這種確定調(diào)用的具體對象的過程稱為“關聯(lián)( binding )”,即把函數(shù)名與某一個類對象捆綁在一起。函數(shù)重載,在編譯時就可確定其調(diào)用的函數(shù)是哪一個;通過對象名調(diào)用虛函數(shù),在編譯時也可確定其調(diào)用的虛函數(shù)屬于哪一個類。其過程稱為“靜態(tài)關聯(lián)( static binding ),因為是在運行前進行關聯(lián)的,又成為早期關聯(lián)( early bindin

10、g )。第10頁,共61頁。6.3 虛函數(shù)通過指針和虛函數(shù)的結(jié)合,在編譯階段是沒法進行關聯(lián)的,因為編譯只作靜態(tài)的語法檢查,光從語句形式pt-display( )無法確定調(diào)用的對象,也就沒法關聯(lián)。出現(xiàn)這種情況,我們可以在運行階段來處理關聯(lián)。在運行階段,基類指針先指向某一個對象,然后通過指針調(diào)用該對象的成員函數(shù)。此時調(diào)用哪個函數(shù)是確定的,沒有不確定因素。例如語句 pt = &g1; pt-display( ); 非常確定的是調(diào)用g1對象的成員函數(shù)display。這種情況由于是在運行階段將虛函數(shù)與某一類對象“綁定”在一起的,因此稱為“動態(tài)關聯(lián)( dynamic binding ),或“滯后關聯(lián)( l

11、ate binding )”。第11頁,共61頁。6.3 虛函數(shù)使用虛函數(shù),要注意只能用virtual 聲明類的成員函數(shù),類外的普通函數(shù)不能聲明成虛函數(shù),因為它沒有繼承的操作。一個成員函數(shù)被聲明成虛函數(shù)后,在同一類族中的類就不能再定義一個非virtual的、但與該函數(shù)具有相同參數(shù)表和返回類型的同名函數(shù)。使用虛函數(shù),系統(tǒng)要有一定的空間開銷。當一個類帶有虛函數(shù)時,編譯系統(tǒng)會為該類構(gòu)造一個虛函數(shù)表( virtual function table, vtable ),它是一個指針數(shù)組,存放每個虛函數(shù)的入口地址。系統(tǒng)在進行動態(tài)關聯(lián)時的時間開銷是很少的,所以多態(tài)性運行效率非常高。第12頁,共61頁。6.3

12、 虛函數(shù)什么情況下使用虛函數(shù)?成員函數(shù)所在的類是否會作為基類?成員函數(shù)被繼承后有沒有可能發(fā)生功能變化,如果兩個因素都具備,就應該將它聲明成虛函數(shù)。如果成員函數(shù)被繼承后功能不變,或派生類用不到該函數(shù),就不要聲明成虛函數(shù)。應考慮對成員函數(shù)的訪問是通過對象名還是基類指針,如果是通過基類指針或引用訪問,則應當聲明為虛函數(shù)。有時基類中定義虛函數(shù)時并不定義它的函數(shù)體,即函數(shù)體為空。其作用只是定義了一個虛函數(shù)名,具體功能留給派生類添加(6.4 節(jié)會討論這種情況)。第13頁,共61頁。6.3 虛函數(shù)虛析構(gòu)函數(shù)問題的引出:我們知道,當派生類對象撤消時,系統(tǒng)先調(diào)用派生類析構(gòu)函數(shù),再調(diào)用基類析構(gòu)函數(shù)。但是,如果用n

13、ew 運算符建立了一個派生類臨時對象,但用一個基類指針指向它,當程序用帶指針參數(shù)的delete 撤消對象時,會發(fā)生讓人不能接受的情況:系統(tǒng)只析構(gòu)基類對象,而不析構(gòu)派生類對象:class pointpublic: point( ) point( ) cout“析構(gòu)基類對象”endl; ;class circle : public pointpublic: circle( ) circle ( ) cout“析構(gòu)派生類對象”endl; private: int radius;int main( ) point *p = new circle; / 指針為指向基類對象指針, / 但實際指向臨時派生類

14、對象 delete p; return 0;第14頁,共61頁。6.3 虛函數(shù)實際上,程序只析構(gòu)了基類對象,而沒有析構(gòu)派生類對象,為什么呢?因為指針p 為基類指針,系統(tǒng)認為它只有基類對象,而與派生類對象無關。實際上,由于該指針被指向了一個臨時派生類對象,所以還應該這個臨時的析構(gòu)派生類對象。解決的辦法:可以將基類的析構(gòu)函數(shù)聲明為虛析構(gòu)函數(shù)。如: virtual point( ) cout“析構(gòu)基類對象”endl; 程序其它部分不動,就行了。當基類的析構(gòu)函數(shù)被定義成virtual,無論指針指向同一類族中的哪一個對象,當撤消對象時,系統(tǒng)會采用動態(tài)關聯(lián),調(diào)用相應的析構(gòu)函數(shù),清理該對象,然后再析構(gòu)基類對

15、象。第15頁,共61頁。6.4 純虛函數(shù)與抽象類前面已經(jīng)提到,有時在基類中將某一成員函數(shù)定為虛函數(shù)并不是基類本身的需要,而是派生類的需要。在基類中預留一個函數(shù)名,具體功能留給派生類根據(jù)需要去定義。在上一節(jié)中基類point 中有定義面積area函數(shù),是因為“點”沒有面積的概念。但是,其直接派生類circle和間接派生類cylinder卻都需要area 函數(shù),而且這兩個area 函數(shù)的功能還不相同,一個是求圓面積,一個是求圓柱體表面積。也許會想到,在基類point 中加一個area 函數(shù),并聲明為虛函數(shù):virtual float area ( ) const return 0; 其返回0表示“點

16、”沒有面積。其實,在基類中并不使用這個函數(shù),其返回值也沒有意義。第16頁,共61頁。6.4 純虛函數(shù)與抽象類為簡化起見,可以不寫出這種無意義的函數(shù)體,只給出函數(shù)的原型,并在后面加上“=0”,如:virtual float area( ) const =0 ; / 純虛函數(shù)這就將area聲明為一個純虛函數(shù)(pure virtual function)純虛函數(shù)的聲明形式virtual 函數(shù)類型 函數(shù)名( 參數(shù)表 ) =0;說明純虛函數(shù)沒有函數(shù)體;最后的“=0”不表示函數(shù)值返回0,它只是形式上的作用,告訴編譯系統(tǒng):這是純虛函數(shù),這是一個聲明語句,以分號結(jié)尾。如果基類中聲明了純虛函數(shù),但派生類中定義該

17、函數(shù),則該虛函數(shù)在派生類中仍為純虛函數(shù)。第17頁,共61頁。6.4 純虛函數(shù)與抽象類純虛函數(shù)的作用是在基類中為其派生類保留一個函數(shù)的名字,以便派生類根據(jù)需要對它進行定義。如果基類中沒有保留函數(shù)名,則無法實現(xiàn)多態(tài)性。第18頁,共61頁。6.4 純虛函數(shù)與抽象類抽象類什么叫抽象類?一般聲明了一個類,用來定義若干對象。但有些類并不是用來生成對象,而是作為基類去建立派生類。這種不用來定義對象,而只作為一種基本類型用做繼承的類,就叫抽象類( abstract class )。由于抽象類常作為基類,我們也稱為抽象基類( abstract base class )。比如,凡是包含純虛函數(shù)的類都叫抽象類。因為

18、純虛函數(shù)不能被調(diào)用,包含純虛函數(shù)的類無法建立對象。抽象類的作用:是作為一個類族的共同基類。即,為一個類族提供一個公共接口。一個類層次結(jié)構(gòu)中可以不包含任何抽象類,每一層次的類都可以建立對象。但是,許多系統(tǒng)的頂層是一個抽象類,甚至頂部有好幾層都是抽象類。第19頁,共61頁。6.4 純虛函數(shù)與抽象類如果由抽象類所派生出的新類中對基類的所有純虛函數(shù)都進行了定義,這個派生類就不是抽象類,可以被調(diào)用,成為可以用來定義對象的具體類( concrete class )。如果由抽象類所派生出的新類中對基類的所有純虛函數(shù)都沒有進行定義,這個派生類就仍然是抽象類。雖然抽象類不能定義對象,但可以定義指向抽象類的數(shù)據(jù)的

19、指針。當派生類成為具體類之后,就可以用這種指針向派生類對象,然后通過該指針調(diào)用虛函數(shù),實現(xiàn)多態(tài)性操作。第20頁,共61頁。編程練習:定義虛函數(shù),基類為SHAPE,派生出圓形、矩形、三角形類。第21頁,共61頁。#include using namespace std;/定義抽象基類Shapeclass Shapepublic:/定義純虛函數(shù);/定義Circle類class Circle:public Shapepublic:Circle(double r):radius(r) /定義虛函數(shù) protected: double radius; /半徑;/定義Rectangle類class Rec

20、tangle:public Shapepublic: Rectangle(double w,double h):width(w),height(h)/定義虛函數(shù) protected: double width,height; ;class Triangle:public Shapepublic: Triangle(double w,double h):width(w),height(h)/定義虛函數(shù) protected: double width,height; ;第22頁,共61頁。#include using namespace std;/定義抽象基類Shapeclass Shapepub

21、lic: virtual double area() const =0; /純虛函數(shù);/定義Circle類class Circle:public Shapepublic:Circle(double r):radius(r) virtual double area() const return 3.14159*radius*radius; /定義虛函數(shù) protected: double radius; /半徑;/定義Rectangle類class Rectangle:public Shapepublic: Rectangle(double w,double h):width(w),height

22、(h) virtual double area() const return width*height; /定義虛函數(shù) protected: double width,height; ;class Triangle:public Shapepublic: Triangle(double w,double h):width(w),height(h) virtual double area() const return 0.5*width*height; /定義虛函數(shù) protected: double width,height; ;第23頁,共61頁。續(xù):定義一個函數(shù)printArea,以對象為

23、形參,輸出三種形狀的面積int main() Circle circle(12.6); /建立Circle類對象circle coutarea of circle =; printArea(circle); /輸出circle的面積 Rectangle rectangle(4.5,8.4); /建立Rectangle類對象rectangle coutarea of rectangle =; printArea(rectangle); /輸出rectangle的面積 Triangle triangle(4.5,8.4); /建立Triangle類對象 coutarea of triangle =

24、; printArea(triangle); /輸出triangle的面積 return 0;第24頁,共61頁。/輸出面積的函數(shù)void printArea(const Shape &s)couts.area()endl; 第25頁,共61頁。6.4 純虛函數(shù)與抽象類多態(tài)性把操作細節(jié)留給類的設計者(專業(yè)人員)去完成,而讓編程人員(類的使用者)只需做一些宏觀性的工作,告訴系統(tǒng)做什么,不必考慮怎么做,簡化了應用程序的編碼工作。因此有人說,多態(tài)性是開啟繼承功能的鑰匙。第26頁,共61頁。Object-OrientedProgramming in C+第七章 輸入輸出流第27頁,共61頁。第一章 C

25、+的初步知識第二章 類和對象第三章 再論類和對象第四章 運算符重載第五章 繼承與派生第六章 多態(tài)性與虛函數(shù)第七章 輸入輸出流第八章 C+工具第28頁,共61頁。7.1 C+的輸入與輸出7.2 標準輸出流7.3 標準出入流7.4 文件操作與文件流7.5 字符串流第29頁,共61頁。7.1 C+的輸入和輸出輸入輸出的含義:從操作系統(tǒng)角度看,每一個與主機相連的輸入輸出設備都被看做一個文件。終端鍵盤是輸入文件,終端顯示器是輸出文件。磁盤或光盤也可以被看作是輸入輸出文件。程序的輸入:指的是從輸入文件將數(shù)據(jù)傳送給程序;程序的輸出:指的是從程序?qū)?shù)據(jù)輸出給輸出文件。C+的輸入輸出包括以下三個方面的內(nèi)容:標準

26、設備輸入輸出,從鍵盤輸入。輸出到顯示器。簡稱標準I/O。以外存儲器文件為對象的輸入輸出。指從磁盤文件中輸入數(shù)據(jù),將數(shù)據(jù)輸出到磁盤文件中。簡稱文件I/O對內(nèi)存中指定的空間進行輸入輸出。通常指定一個字符數(shù)組作為存儲空間,它稱為字符串輸入輸出,簡稱串I/OC+采取了不同的方法,實現(xiàn)這三種輸入輸出。第30頁,共61頁。7.1 C+的輸入和輸出C+輸入輸出流C+的輸入輸出流是指由若干字節(jié)組成的字節(jié)序列。在內(nèi)存中,系統(tǒng)為每一個數(shù)據(jù)流開辟一個緩沖區(qū),用來存放流中的數(shù)據(jù)。當使用 cout 和插入符“”從輸入緩沖區(qū)提取數(shù)據(jù),送給程序中的相關變量。總之,內(nèi)存緩沖區(qū)中的數(shù)據(jù)就是流。第31頁,共61頁。7.1 C+的

27、輸入和輸出流類與流對象:在C+中,輸入輸出流被定義成類,C+的 I/O 庫中的類稱為流類( stream class )。用流類定義的對象稱為流對象。cout 和 cin 并不是C+提供的語句,它們是iostream類的對象。正如C+沒有提供賦值語句,只提供了賦值表達式(表達式后面加分號,形成語句)。在 iostream 頭文件中重載運算符:“”在C+中是位移運算符,由于在 iostream 頭文件中對它們進行了重載,使它們能用做標準輸入輸出運算符,所以,在用它們的程序中必須使用 #include 語句把iostream類包含到程序中。下面我們來看看 I/O 類庫中類的情況。第32頁,共61頁

28、。7.1 C+的輸入和輸出I/O 類庫中常用的流類 strstreamstrstreamstrstream輸入字符串流類輸出字符串流類輸入輸出字符串流類istrstreamostrstreamstrstreamfstreamfstreamfstream輸入文件流類輸出文件流類輸入輸出文件流類ifstreamofstreamfstreamiostreamiostreamiostream通用輸入流和其他輸入流的基類通用輸出流和其他輸出流的基類通用輸入輸出流和其他輸入輸出流的基類istreamostreamiostreamIostream抽象基類ios在哪個頭文件中聲明作 用類 名第33頁,共61頁

29、。7.1 C+的輸入和輸出iostream 文件中定義的4種流對象stderrostream_withassign屏幕標準錯誤流clogstderrostream_withassign屏幕標準錯誤流cerrstdoutostream_withassign屏幕標準輸出流coutstdinistream_withassign鍵盤標準輸入流cinC語言對應文件對應的類對應設備含義對象說明 cin 是 istream 的派生類 istream_withassign 的對象,它是從鍵盤輸入數(shù)據(jù)流到內(nèi)存; cout 是 ostream 的派生類 ostream_withassign 的對象,它從內(nèi)存輸出數(shù)

30、據(jù)流到顯示器; cerr 和 clog 相似,均為向顯示器輸出出錯信息 第34頁,共61頁。7.2 標準輸出流clog 流對象:也是標準出錯流,是console log 的縮寫。作用和 cerr 相同。區(qū)別在于,cerr 不經(jīng)過緩沖區(qū),直接向顯示器輸出,而 clog 經(jīng)過緩沖區(qū),緩沖區(qū)裝滿后或遇到endl 時,向顯示器輸出。 #include #include void main( ) float a,b,c,disc; cout abc; if (a=0) cerr a is equal to zero,error!endl; else if (disc=b*b-4*a*c)0) cerr

31、disc=b*b-4*a*c 0 endl; else coutx1=(-b+sqrt(disc)/(2*a)endl; coutx2=(-b-sqrt(disc)/(2*a)endl; 第35頁,共61頁。7.2 標準輸出流格式輸出:輸出數(shù)據(jù)時,為簡便起見往往不指定輸出格式。但也可以指定輸出格式。輸出格式有兩種方法: 使用控制符輸出格式; 使用流對象的有關成員函數(shù)。使用控制符輸出格式:這些控制符是在頭文件 iomanip中定義。程序必須包含該頭文件???制 符作 用dec, hex, oct分別設置整數(shù)的基數(shù)為10、16、8setbase (n)設置整數(shù)基數(shù)為n ( n 為10,16,8三者

32、之一)setfill ( c ) 設置填充字符c,c是字符常量或變量setprecision (n)設置實數(shù)精度為n位setw (n)設置字段寬度為 nsetiosflags (ios:left / right )輸出數(shù)據(jù)左/右對齊resetioflags ( )終止已設置的輸出格式,在括號中指定內(nèi)容第36頁,共61頁。7.2 標準輸出流#include #include int main( ) int a=123; char *pt = “China”; double pi = 22.0/7.0; cout “dec:”decaendl; cout “hec:”hexaendl; cout

33、“oct:”octaendl; coutsetw(10)ptendl; coutsetfill(*)setw(10)ptendl; cout“pi=”piendl; cout“pi=“setprecision(4)piendl; cout“pi=“setiosflags (ios:fixed) piendl; return 0;第37頁,共61頁。7.2 標準輸出流用流成員函數(shù) put 輸出字符我們已經(jīng)知道,程序中一般用 cout 實現(xiàn)輸出,cout 流在內(nèi)存中有相應的緩沖區(qū)。有時,我們想只輸出一個字符,ostream 類提供了 put 成員函數(shù)來滿足這一特殊需求:#include int m

34、ain( ) char *a = BASIC; for (int i=4; i=0; i-) cout.put(*(a+i); cout.put(n); return 0;第38頁,共61頁。7.3 標準輸入流cin 流:cin 流是 istream類的對象。它從標準輸入設備(鍵盤)獲取數(shù)據(jù),程序中的變量通過流提取符“”從流中提取數(shù)據(jù)。用于字符輸入的流成員函數(shù):用get 函數(shù)讀入一個字符:get函數(shù)有三中形式:無參數(shù)、有一個參數(shù)和3個參數(shù)的形式。不帶參數(shù)的 get 函數(shù):其調(diào)用形式為:cin.get ( )#include int main( ) char c; cout“input a se

35、ntence,please: endl; while (c=cin.get()!=EOF) coutc; return 0;第39頁,共61頁。7.3 標準輸入流有一個參數(shù)的get函數(shù):調(diào)用形式為:cin.get(ch)。作用是從輸入流中讀取一個字符,并賦給變量 ch 。#include int main( ) char c; coutinpute a sectence,please: endl; while (cin.get(c) cout.put(c); coutendendl; return 0;第40頁,共61頁。7.3 標準輸入流有三個參數(shù)的 get 函數(shù):調(diào)用形式: cin.get

36、 ( 字符數(shù)組/字符指針,字符個數(shù)n,終止字符)其作用是,從輸入流中讀取 n-1 個字符,并賦給指定的數(shù)組(或指針指向的數(shù)組)。如果在讀取中遇見終止字符,則提前結(jié)束讀取操作。#include int main( ) char ch20; coutinpute a sectence,please: endl; cin.get(ch,18,n); coutchendl; return 0;第41頁,共61頁。7.3 標準輸入流用成員函數(shù)getline 讀入一行字符。調(diào)用形式: getline ( 字符數(shù)組/字符指針, 字符個數(shù)n, 終止字符 )作用是從讀入流中讀取一行字符,并賦給字符數(shù)組。第42頁

37、,共61頁。7.3 標準輸入流istream 類其它成員函數(shù)eof 函數(shù):表示文件結(jié)束。從輸入流中讀入文件,當達到文件尾,則eof函數(shù)值為非0(表示真),否則為0 (假)。#include int main( ) char c; while (!cin.eof() if (c=cin.get()!= ) cout.put(c); else cout.put(_); return 0;第43頁,共61頁。7.4 文件操作與文件流文件的概念:文件一般是指存儲在外部介質(zhì)上的數(shù)據(jù)集合。我們主要是指數(shù)據(jù)文件。根據(jù)數(shù)據(jù)的組織形式,數(shù)據(jù)文件分為:ASCII文件:又稱為文本文件,它的每一個字節(jié)放一個ASCII

38、代碼,代表一個字符。二進制文件:又稱為內(nèi)部格式文件,它把數(shù)據(jù)按其在內(nèi)存中的存儲形式遠洋輸出到磁盤上存放。對于字符信息,在內(nèi)存中是以ASCII代碼形式存放的,因此,無論用ASCII文件輸出,還是用二進制文件輸出,其數(shù)據(jù)形式是一樣的。但是對于數(shù)值數(shù)據(jù),二者是不同的。第44頁,共61頁。7.4 文件操作與文件流文件流類與文件流對象:文件流是以外存文件為輸入輸出對象的數(shù)據(jù)流。輸出文件流是從內(nèi)存流向外存文件的數(shù)據(jù);輸入文件流是從外存文件流向內(nèi)存的數(shù)據(jù)。文件與文件流的區(qū)別:文件流不是文件,而只是以文件為輸入輸出對象的流。C+定義的文件類: ifstream 類,是 istream 類派生,用于從磁盤文件輸

39、入數(shù)據(jù)。 ofstream 是ostream 類派生,用于向磁盤文件的輸出。 fstream 是 iostream 類的派生,用于磁盤文件的輸入輸出。第45頁,共61頁。7.4 文件操作與文件流文件的打開與關閉打開磁盤文件:打開文件是指在文件讀寫之前做必要的準備工作。包括: 為文件對象和指定的磁盤文件建立關聯(lián),以便使文件流流向指定的磁盤文件; 指定文件的工作方式,如,是讀文件還是寫文件,是操作ASCII文件還是二進制文件。打開文件有兩種實現(xiàn)方式:調(diào)用文件流的成員函數(shù)open。一般形式為:文件流對象.open ( 磁盤文件名, 輸入輸出方式 );注意,磁盤文件名可以包括路徑,省略路徑則默認為當前

40、目錄。如: ofstream outfile; / 定義ofstream 類對象 outfile outfile.open (“fi.dat, ios:out ); / 使文件流與f1.dat文件建立關聯(lián)第46頁,共61頁。7.4 文件操作與文件流在定義文件流對象時指定參數(shù):比如ostream outfile (“f1.dat”, ios:out );一般常用這種形式來打開文件。第47頁,共61頁。7.4 文件操作與文件流文件的輸入輸出方式設置值:方式作用ios : in以輸入方式打開文件ios : out以輸出方式打開文件。若文件存在,則清除原內(nèi)容ios : app以輸出方式打開文件。寫入的

41、數(shù)據(jù)增加在文件末尾ios : ate打開已有文件,文件指針指向文件末尾ios : trunc打開文件,若文件存在,則刪除原數(shù)據(jù)ios : binary以二進制方式打開文件ios : in | ios : out以讀寫方式打開文件ios : out | ios : binary以二進制方式打開輸出文件ios : in | ios : binar以二進制方式打開輸入文件第48頁,共61頁。7.4 文件操作與文件流關閉磁盤文件:即解除該磁盤文件與文件流的關聯(lián)。關閉文件的成員函數(shù):outfile.close ( );第49頁,共61頁。7.5 字符串流字符串流的概念:文件流是以外存文件為輸入輸出對象的

42、數(shù)據(jù)流,而字符串流是將數(shù)據(jù)輸出到內(nèi)存中的字符數(shù)組,或從字符數(shù)組讀入數(shù)據(jù)。字符串流也稱內(nèi)存流。字符串流緩沖區(qū):字符串流也有緩沖區(qū)。一開始,緩沖區(qū)為空。如果向字符數(shù)組存入數(shù)據(jù),隨著向流插入數(shù)據(jù),流緩沖區(qū)中的數(shù)據(jù)不斷增加。當緩沖區(qū)滿或遇到換行符,緩沖區(qū)內(nèi)容變?nèi)看嫒胱址麛?shù)組。如果是從字符數(shù)組讀數(shù)據(jù),先將字符數(shù)組中的數(shù)據(jù)送到緩沖區(qū),然后從緩沖區(qū)提取數(shù)據(jù)賦給有關變量。第50頁,共61頁。7.5 字符串流數(shù)據(jù)存入字符數(shù)組之前,先要將數(shù)據(jù)轉(zhuǎn)換成ASCII代碼,然后放入緩沖區(qū),再從緩沖區(qū)送到字符數(shù)組。字符串流類的類型有:Istrstream 類;Ostrstream 類;Strstream 類。文件流類和字符

43、串流類都是ostream類、istream類和iostream 類的派生類。第51頁,共61頁。7.5 字符串流建立輸出字符串流對象:ostrstream 類提供的構(gòu)造函數(shù)原型為: ostrstream : ostrstream (char *buffer, int n, int mode=ios:out );其中:buffer是指向字符數(shù)組首元素的指針;n 為指定的流緩沖區(qū)大小,一般與字符數(shù)組大小相同;第三個參數(shù)可選,默認為ios:;out方式,可以用以下語句建立輸出字符串流對象并與字符數(shù)組建立關聯(lián):ostrstream strout (ch1,20);作用是建立輸出字符串流對象 strou

44、t 與字符數(shù)組ch1關聯(lián),緩沖區(qū)大小為20。第52頁,共61頁。7.5 字符串流建立輸入輸出字符串流對象:strstream 類提供的構(gòu)造函數(shù)原型為:strstream : strstream (char *buffer, int n, int mode );可以用以下語句建立輸入輸出字符流對象:strstream strio (ch3, sizeof(ch3),ios:in|ios:out);作用是建立輸入輸出字符串流對象,以字符數(shù)組ch3為輸入輸出對象,流緩沖區(qū)大小與ch3相同。第53頁,共61頁。7.5 字符串流例:將三個學生數(shù)據(jù)保存在字符數(shù)組中。#include #include us

45、ing namespace std;struct student int num; char name10; int score;void main()student stud3= 1001,Li,78,1002,Liu,98,1003,Ge,90; char c50; ostrstream strout (c,30); for (int i=0;i3;i+) studi.score; stroutends; coutarray c:cendl; 第54頁,共61頁。Object-OrientedProgramming in C+第八章 C+工

46、具第55頁,共61頁。8.1 命名空間8.2 使用早期的函數(shù)庫第56頁,共61頁。8.1 命名空間本課程的各章節(jié)的程序中,都用到了這樣的語句:using namespac std;這就是命名空間std。為什么需要命名空間?C語言定義了3個作用域,即文件域,函數(shù)域和復合語句域。C+又引入了類作用域。不同的作用域中可以用相同的變量名,互不干擾。但是,如果是在不同的庫文件( *.h )中,有相同的變量名和類名,而不巧又在被一個程序包含、主文件中又調(diào)用了該變量,定義了該類對象,于是引起矛盾沖突。第57頁,共61頁。8.1 命名空間什么是命名空間?為了解決這個問題,ANSI C+增加了命名空間的概念。簡單地說,就是ANSI C+引入的,可以由用戶命名的內(nèi)存區(qū)域,

溫馨提示

  • 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

提交評論