C++編程基礎(chǔ)課件_第1頁
C++編程基礎(chǔ)課件_第2頁
C++編程基礎(chǔ)課件_第3頁
C++編程基礎(chǔ)課件_第4頁
C++編程基礎(chǔ)課件_第5頁
已閱讀5頁,還剩516頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

C++基礎(chǔ)

2.1類和對象

2.1.1從結(jié)構(gòu)到類

2.1.2類的定義

一般地分為聲明部分和實現(xiàn)部分。聲明部分是用來聲明該類中的成員,含數(shù)據(jù)成員和成員函數(shù)的聲明。成員函數(shù)是用來對數(shù)據(jù)成員進行操作的。實現(xiàn)部分是用來對成員函數(shù)的定義。聲明部分將告訴使用者“幹什麼”,而實現(xiàn)部分是告訴使用者“怎麼幹”。

定義類的一般格式如下:

class<類名> {private: [<私有數(shù)據(jù)和函數(shù)>] public: [<公有數(shù)據(jù)和函數(shù)>]};

<各個成員函數(shù)的實現(xiàn)>class的後面是用戶定義的類名,類中的數(shù)據(jù)和函數(shù)是類的成員,分別稱為數(shù)據(jù)成員和成員函數(shù)。由於數(shù)據(jù)成員是用變數(shù)來描述的,因此數(shù)據(jù)成員又可稱為“成員變數(shù)”。

public和private聲明了類中的成員和程式其他部分的關(guān)係。對於public類成員來說,它們是公有的,能被外面的程式訪問;對於private類成員來說,它們是私有的,只能由類中的函數(shù)所使用,而不能被外面的程式所訪問。

<各個成員函數(shù)的實現(xiàn)>是類定義中的實現(xiàn)部分,包含所有在類體中聲明的函數(shù)的定義。如果一個成員函數(shù)在類體中定義,實現(xiàn)部分將不出現(xiàn)。如果所有的成員函數(shù)都在類體中定義,則實現(xiàn)部分可以省略。當類的成員函數(shù)的函數(shù)體在類的外部定義時,必須由作用域運算符“::”來通知編譯系統(tǒng)該函數(shù)所屬的類。

2.1類和對象

定義類時還應(yīng)注意:(1)

在“public:”或“private:”後面定義的所有成員都是公有或私有的,直到下一個“public:”或“private:”出現(xiàn)為止。若成員前面沒有類似“public:”或“private:”,則所定義的成員是private(私有),這是類的默認設(shè)置。(2)

關(guān)鍵字public和private可以在類中出現(xiàn)多次,且前後的順序沒有關(guān)係。但最好先聲明公有成員,後聲明私有成員,因為public成員是用戶最關(guān)心的。(3)

除了public和private外,關(guān)鍵字protected(保護)也可修飾成員的類型,它與private兩者基本相似,但在類的繼承時有所不同。(4)

數(shù)據(jù)成員的類型可以是任意的,包含整型、浮點型、字元型、數(shù)組、指針等,也可以是另一個類的對象,但不允許對所定義的成員變數(shù)進行初始化。

(5)儘量將類單獨存放在一個檔中或?qū)㈩惖穆暶鞣旁?h檔中而將成員函數(shù)的實現(xiàn)放在與.h檔同名的.cpp檔中。以後將會看到,VisualC++6.0為用戶創(chuàng)建的應(yīng)用程式框架中都是將各個類以.h和同名的.cpp檔來組織的。

2.1類和對象2.1.3對象的定義

一個類定義後,就可以定義該類的對象,格式: <類名><對象名列表>

類名是用戶已定義過的類的識別字,對象名可以有一個或多個,多個時要用逗號分隔。被定義的對象既可以是一個普通對象,也可以是一個數(shù)組對象或指針對象。一個對象的成員就是該對象的類所定義的成員,引用(訪問)時可用下列方式:

<對象名>.<成員名> <對象名>.<成員名>(<參數(shù)表>)。前者用來表示引用數(shù)據(jù)成員,後者用來表示引用成員函數(shù)?!?”是一個成員運算符,用來引用對象的成員對於指針對象的成員引用可用下列方式:

<對象指針名>-><成員名> <對象指針名>-><成員名>(<參數(shù)表>)“->”與“.”運算符的區(qū)別是:“->”用來訪問指針對象的成員,“.”用來訪問一般對象的成員。需要說明的是,下麵的兩種表示是等價的:

<對象指針名>-><成員名> (*<對象指針名>).<成員名>

這對於成員函數(shù)也適用,例如two->GetAverage()和(*two).GetAverage()是等價的,由於成員運算符“.”的優(yōu)先順序比取內(nèi)容運算符“*”高。若結(jié)構(gòu)成員前面沒有“public:”或“private:”,則所定義的成員是public(公有)。

2.2類的成員及特性

2.2.1構(gòu)造函數(shù)

使用構(gòu)造函數(shù)能給數(shù)據(jù)成員自動設(shè)置某些初始值。它的最大特點是在對象建立時它會被自動執(zhí)行,因此用於變數(shù)、對象的初始化代碼一般放在構(gòu)造函數(shù)中。構(gòu)造函數(shù)必須與相應(yīng)的類同名,可以帶參數(shù),可以不帶參數(shù),而且可以重載。但不能指定函數(shù)返回值的類型,也不能指定為void類型。例如:classCStuScore { public: CStuScore(charstr[12]) //第一個構(gòu)造函數(shù)

{ strcpy(strName,str); } CStuScore(charstr[12],charstrNO[9]) //第二個構(gòu)造函數(shù)

{ strcpy(strName,str); strcpy(strStuNO,strNO);} char strName[12]; //姓名

char strStuNO[9]; //學號

...}

(1)

程式中的strcpy是一個庫函數(shù),用來複製字串,使用時要頭檔string.h。

(2)

類定義時,如沒有定義任何構(gòu)造函數(shù),編譯器自動為類生成一個不帶任何參數(shù)的默認構(gòu)造函數(shù)。

(3)

由於構(gòu)造函數(shù)的參數(shù)只能在定義對象時指定。

2.2類的成員及特性2.2.2析構(gòu)函數(shù)

與構(gòu)造函數(shù)相對應(yīng)的另一種特殊的C++成員函數(shù)是析構(gòu)函數(shù),它的功能是用來釋放一個對象,在對象刪除前,用它來做一些清理工作,它與構(gòu)造函數(shù)的功能正好相反。 析構(gòu)函數(shù)也要與相應(yīng)的類同名,並在名稱前面加上一個“~”符號。每一個類只有唯一的一個析構(gòu)函數(shù),沒有任何參數(shù),也不返回任何值,也不能被重載。例如:

classCStuScore { public: ... ~CStuScore() { } //析構(gòu)函數(shù)

...}

同樣,如果一個類中沒有定義析構(gòu)函數(shù)時,則編譯系統(tǒng)也會為類自動生成一個默認析構(gòu)函數(shù),其格式如下(以類CStuScore為例):

~CStuScore() //默認析構(gòu)函數(shù)的形式

{}需要說明的是,析構(gòu)函數(shù)只有在下列兩種情況下才會被自動調(diào)用:

(1)

當對象定義在一個函數(shù)體中,該函數(shù)調(diào)用結(jié)束後,析構(gòu)函數(shù)被自動調(diào)用。

(2)

用new為對象分配動態(tài)記憶體後,當使用delete釋放對象時,析構(gòu)函數(shù)被自動調(diào)用。

2.2類的成員及特性2.2.3對象成員初始化 構(gòu)造函數(shù)定義格式:

<類名>::<構(gòu)造函數(shù)名>(形參表):對象1(參數(shù)表),對象2(參數(shù)表),…,對象n(參數(shù)表) {…… }

對象1、對象2、…、對象n就是該類使用的其他類的對象,冒號“:”後面的列表稱為成員初始化列表。說明:(1)

類的對象成員必須初始化,但不能將對象成員直接在構(gòu)造函數(shù)體內(nèi)進行初始化,例如下麵的初始化是不可以的:

CRect(intleft,inttop,intright,intbottom) { ptCenter=CPoint((left+right)/2,(top+bottom)/2); size=CSize(right-left,bottom-top);}(2)

對象成員初始化時,必須有相應(yīng)的構(gòu)造函數(shù),且多個對象成員的構(gòu)造次序不是按初始化成員列表的順序,而是按各類聲明的先後次序進行的,從上例的運行結(jié)果可以得到證明。(3)

對象成員初始化也可在類構(gòu)造函數(shù)定義時進行。(4)事實上,成員初始化列表也可用於類中的普通數(shù)據(jù)成員的初始化。

2.2類的成員及特性2.2.4常類型

常對象 常對象是指對象常量,定義格式:<類名>const<對象名>

定義常對象時要進行初始化,並且該對象不能再被更新,修飾符const可以放在類名後面,也可以放在類名前面。

常成員函數(shù)

使用const關(guān)鍵字進行聲明的成員函數(shù)。只有常成員函數(shù)才有資格操作常量或常對象。說明格式: <類型說明符><函數(shù)名>(<參數(shù)表>)const;

const是加在函數(shù)聲明後面的類型修飾符,它是函數(shù)類型的一個組成部分,因此在函數(shù)實現(xiàn)部分也要帶const關(guān)鍵字。常成員函數(shù)還可以理解為一個“只讀”函數(shù),它不能更改數(shù)據(jù)成員的值,也不能調(diào)用那些引起數(shù)據(jù)成員值變化的成員函數(shù),只能調(diào)用const成員函數(shù)。

常數(shù)據(jù)成員 類型修飾符const不僅可以說明成員函數(shù),也可以說明數(shù)據(jù)成員。由於const類型對象必須被初始化,並且不能更新,因此,在類中聲明const數(shù)據(jù)成員後,只能通過構(gòu)造函數(shù)成員初始化方式來對常數(shù)據(jù)成員初始化。

2.2類的成員及特性2.2.5this指針

類中總有一個特殊的指針this,它指向類自己。該指針可以在類中訪問類的成員變數(shù)和成員函數(shù)。但在實際運用中,一般不需要顯式地使用this指針來引用成員。

[例Ex_This]this指針的使用。

#include<iostream.h> classCOne { public: COne() {x=y=0;} COne(inta,intb) {x=a; y=b;} //對象引用作函數(shù)參數(shù)

voidcopy(COne&a); voidprint() {cout<<x<<","<<y<<endl;} private: intx,y;}; voidCOne::copy(COne&a) { if(this==&a)return; *this=a;}

voidmain() { COneone,two(3,4); one.print(); one.copy(two); one.print();}

運行結(jié)果:

0,0 3,4

函數(shù)copy代碼中,*this=a;是將形參a獲得的某對象的值賦給操作該成員函數(shù)的對象。在本例中,就是將對象two賦給對象one。2.2類的成員及特性2.2.6類的作用域和對象的生存期類的作用域是指在類的定義中由一對花括弧所括起來的部分。類作用域中定義的變數(shù)不能使用auto,register和extern等修飾符,只能使用static修飾符,而定義的函數(shù)也不能用extern修飾符。檔作用域中可以包含類作用域,類作用域小於檔作用域。某個類A中某個成員M在下列情況下具有類A的作用域:(1)

成員M出現(xiàn)在類A的某個成員函數(shù)中,並且該成員函數(shù)沒有定義同名識別字。(2)

成員M出現(xiàn)在a.M或A::M運算式中,其中a是A的對象。(3)

成員M出現(xiàn)在pa->M這樣的運算式中,其中pa是一個指向A類對象的指針。對象的生存期是指對象從被創(chuàng)建開始到被釋放為止的時間。生存期的不同對象分:(1)

局部對象:當對象被定義時調(diào)用構(gòu)造函數(shù),該對象被創(chuàng)建,當程式退出定義該對象所在的函數(shù)體或程式塊時,調(diào)用析構(gòu)函數(shù),釋放該對象。(2)

靜態(tài)對象:當程式第一次執(zhí)行所定義的靜態(tài)對象時,該對象被創(chuàng)建,當程式結(jié)束時,該對象被釋放。(3)

全局對象:當程式開始時,調(diào)用構(gòu)造函數(shù)創(chuàng)建該對象,當程式結(jié)束時調(diào)用析構(gòu)函數(shù)釋放該對象。局部對象是被定義在一個函數(shù)體或程式塊內(nèi)的,它的作用域小,生存期也短。靜態(tài)對象是被定義在一個檔中,它的作用域從定義時起到檔結(jié)束時止。它的作用域比較大,它的生存期也比較長。全局對象是被定義在某個檔中,而它的作用域卻在包含該檔的整個程式中,它的作用域是最大的,它的生存期也是最長的。

2.2類的成員及特性2.2.7靜態(tài)成員

靜態(tài)數(shù)據(jù)成員

靜態(tài)數(shù)據(jù)成員是同一個類中所有對象共用的成員。使用靜態(tài)數(shù)據(jù)成員可以節(jié)省記憶體。靜態(tài)數(shù)據(jù)成員的值對每個對象都是一樣,但它的值是可以更新的。靜態(tài)數(shù)據(jù)成員是靜態(tài)存儲的,具有靜態(tài)生存期。它是這樣的定義的:

(1)

使用關(guān)鍵字static聲明靜態(tài)數(shù)據(jù)成員。

(2)

對靜態(tài)數(shù)據(jù)成員進行初始化。由於靜態(tài)數(shù)據(jù)成員需要系統(tǒng)為其分配記憶體空間,因此不能在類聲明中進行初始化。靜態(tài)數(shù)據(jù)成員初始化須在類的外部進行,且與一般數(shù)據(jù)成員初始化不同,它的格式如下:

<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<值>靜態(tài)成員函數(shù)

靜態(tài)成員函數(shù)屬於類的靜態(tài)成員,但它不是對象成員。因此,對靜態(tài)成員的引用不要用對象名。在靜態(tài)成員函數(shù)的實現(xiàn)中不能直接引用類中的非靜態(tài)成員,但可以引用類中的靜態(tài)成員。如果靜態(tài)成員函數(shù)中一定要引用非靜態(tài)成員時,則可通過對象來引用。公有的靜態(tài)成員函數(shù)既可以通過相應(yīng)的對象訪問,也可以通過其所屬的類名來引用。

2.2類的成員及特性2.2.8友元

類的重要特性是使數(shù)據(jù)封裝與隱藏,但同時也給外部函數(shù)訪問類中的私有和保護類型數(shù)據(jù)成員帶來了不便,為此,C++使用一個特殊的函數(shù)——“友元函數(shù)”來解決這個問題。

“友元函數(shù)”必須在類中進行聲明而在類外定義,聲明時須在函數(shù)類型前面加上關(guān)鍵字friend。友元函數(shù)雖不是類的成員函數(shù),但它可以訪問類中的私有和保護類型數(shù)據(jù)成員。

friend除了可以定義友元函數(shù)外,還可以定義友元類,即一個類可以作另一個類的友元。當一個類作為另一個類的友元時,這就意味著這個類的所有成員函數(shù)都是另一個類的友元函數(shù)。

2.3繼承和派生類

通過繼承可以在一個一般類的基礎(chǔ)上建立新類。被繼承的類稱為基類(baseclass),在基類上建立的新類稱為派生類(derivedclass)。如果一個類只有一個基類則稱為單繼承,否則稱為多繼承。通過進行類繼承,可以提高程式的可重用性和可維護性。

2.3.1單繼承 從一個基類定義一個派生類可按下列格式:

class<派生類名>:[<繼承方式>]<基類名> { [<派生類的成員>] };

繼承方式有三種:public(公有)、private(私有)及protected(保護),若繼承方式?jīng)]有指定,則被指定為默認的public方式。繼承方式?jīng)Q定了派生類繼承基類的屬性及其使用權(quán)限。公有繼承(public)公有繼承的特點是基類的公有成員和保護成員作為派生類的成員時,它們都保持原有的狀態(tài),而基類的私有成員仍然是私有的。注意的是:派生類中或派生類的對象可以使用基類的公有成員(包括保護成員),例如CStudent類的成員函數(shù)Print中調(diào)用了基類CPerson的Output函數(shù),stu對象調(diào)用了基類的SetData成員函數(shù),但基類或基類的對象卻不可以使用派生類的成員。

2.3繼承和派生類私有繼承(private)

特點是基類的公有成員和保護成員都作為派生類的私有成員,並且不能被這個派生類的子類所訪問。保護繼承(protected)

特點是基類的所有公有成員和保護成員都成為派生類的保護成員,並且只能被它的派生類成員函數(shù)或友元訪問,基類的私有成員仍然是私有的。注意:一定要區(qū)分清楚派生類的對象和派生類中的成員函數(shù)對基類的訪問是不同的。例如,在公有繼承時,派生類的對象可以訪問基類中的公有成員,派生類的成員函數(shù)可以訪問基類中的公有成員和保護成員。在私有繼承和保護繼承時,基類的所有成員不能被派生類的對象訪問,而派生類的成員函數(shù)可以訪問基類中的公有成員和保護成員。2.3繼承和派生類2.3.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)

派生類對象在建立時,先執(zhí)行基類的構(gòu)造函數(shù),然後執(zhí)行派生類的構(gòu)造函數(shù)。但對於析構(gòu)函數(shù)來說,其順序剛好相反,先執(zhí)行派生類的析構(gòu)函數(shù),而後執(zhí)行基類的析構(gòu)函數(shù)。注意:基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被派生類繼承。 派生類進行初始化對基類設(shè)置初值格式:

<派生類名>(總參表):<基類1>(參數(shù)表1),<基類2>(參數(shù)表2),…,<基類n>(參數(shù)表n),對象成員1(對象成員參數(shù)表1),對象成員2(對象成員參數(shù)表2),…,對象成員n(對象成員參數(shù)表n) {...}

構(gòu)造函數(shù)總參表後面給出的是需要用參數(shù)初始化的基類名、對象成員名及各自對應(yīng)的參數(shù)表,基類名和對象成員名之間的順序可以是任意的,且對於使用默認構(gòu)造函數(shù)的基類和對象成員,可以不列出基類名和對象成員名。這裏所說的對象成員是指在派生類中新聲明的數(shù)據(jù)成員,它屬於另外一個類的對象。對象成員必須在初始化列表中進行初始化。2.3繼承和派生類2.3.3多繼承在類的繼承中允許一個派生類繼承多個基類,這種多繼承的方式可使派生類具有多個基類的特性,因而不僅使程式結(jié)構(gòu)清晰,且大大提高了程式代碼的可重用性。 多繼承下派生類的定義是按下麵的格式:

class<派生類名>:[<繼承方式1>]<基類名1>,[<繼承方式2>]<基類名2>,... { [<派生類的成員>] };

其中的繼承方式還是前面的三種:public、private和protected。 例如:

classA {...} classB {...} classC:publicA,privateB {...}

派生類C的成員包含了基類A中成員和B中成員以及該類本身的成員。

C++允許一個基類有多個派生類(稱為多重派生)以及從一個基類的派生類中再進行多個層次的派生。

C++進階

3.1多態(tài)和虛函數(shù)

多態(tài)(Polymorphism)編譯時多態(tài):重載運行時多態(tài):虛函數(shù)3.1多態(tài)和虛函數(shù)

3.1.1虛函數(shù)

[例Ex_VirtualFunc]虛函數(shù)的使用。#include<iostream.h>classCShape{public: virtualfloatarea() {return0.0;} };classCTriangle:publicCShape{public:CTriangle(floath,floatw){H=h; W=w; }floatarea(){return(float)(H*W*0.5);}private: floatH,W;};classCCircle:publicCShape{public: CCircle(floatr) { R=r; } floatarea() {return(float)(3.14159265*R*R);} private: floatR;};voidmain(){ CShape*s[2]; s[0]=newCTriangle(3,4); cout<<s[0]->area()<<endl; s[1]=newCCircle(5); cout<<s[1]->area()<<endl;}

運行結(jié)果為:

6 78.5398

3.1多態(tài)和虛函數(shù)

說明:

(1)

虛函數(shù)在重新定義時參數(shù)的個數(shù)和類型必須和基類中的虛函數(shù)完全匹配,這一點和函數(shù)重載完全不同。

(2)

虛函數(shù)所具備的上述功能,只有通過基類指針才可實現(xiàn)。虛函數(shù)在用對象名和成員運算符以正常方式調(diào)用時,不能達到其效果。

(3)

如果不使用new來創(chuàng)建相應(yīng)的派生類對象,也可用下列方法來實現(xiàn):

voidmain() { CShape*p1,*p2;

CTriangletri(3,4); CCirclecir(5); p1=&tri;

p2=○ cout<<p1->area()<<endl; cout<<p2->area()<<endl;}

(4)

虛函數(shù)必須是類的一個成員函數(shù),不能是友元函數(shù),不能是靜態(tài)的成員函數(shù)。

(5)可把析構(gòu)函數(shù)定義為虛函數(shù),但不能將構(gòu)造函數(shù)定義為虛函數(shù)。通常在釋放基類及其派生類中的動態(tài)申請的存儲空間時,也要把析構(gòu)函數(shù)定義為虛函數(shù),以便實現(xiàn)撤銷對象時的多態(tài)性。

3.1多態(tài)和虛函數(shù)3.1.2純虛函數(shù)和抽象類

定義一個基類時,會遇到這樣的情況:無法定義基類中虛函數(shù)的具體實現(xiàn),其實現(xiàn)完全依賴於其不同的派生類。例如,一個“形狀類”由於沒有確定的具體形狀,因此其計算面積的函數(shù)也就無法實現(xiàn)。這時可將基類中的虛函數(shù)聲明為純虛函數(shù)。

聲明純虛函數(shù)的一般格式為:

virtual<函數(shù)類型><函數(shù)名>(<形數(shù)表>)=0;它與一般虛函數(shù)不同的是:在純虛函數(shù)的形參表後面多了個“=0”。把函數(shù)名賦於0,本質(zhì)上是將指向函數(shù)的指針的初值賦為0。需要說明的是,純虛函數(shù)不能有具體的實現(xiàn)代碼。

抽象類是指至少包含一個純虛函數(shù)的特殊的類。它本身不能被實例化,也就是說不能聲明一個抽象類的對象。必須通過繼承得到派生類後,在派生類中定義了純虛函數(shù)的具有實現(xiàn)代碼,才能獲得一個派生類的對象。與虛函數(shù)使用方法相同,也可以聲明指向抽象類的指針,雖然該指針不能指向任何抽象類的對象,但可以通過該指針獲得對派生類成員函數(shù)的調(diào)用。事實上,純虛函數(shù)是一個特殊的虛函數(shù)。

3.2運算符重載

3.2.1運算符重載的語法

<函數(shù)類型><類名>::operator<重載的運算符>(<形參表>) {…} //函數(shù)體 運算符重載函數(shù)的函數(shù)是以特殊的關(guān)鍵字operator開始的,因而編譯器很容易與其他的函數(shù)名區(qū)分開來。

重載的運算符必須是合法的運算符。說明:(1)

當用成員函數(shù)實現(xiàn)雙目運算符的重載時,運算符的左運算元一定是對象,右運算元作為調(diào)用運算符重載函數(shù)的參數(shù),參數(shù)可以是對象、對象的引用或是其他類型的參數(shù)。(2)

不是所有的運算符都可以重載。不允許重載的運算符除三目運算符“?:”外,還有成員操作符“.”、成員指針取值操作符“*”、作用域操作符“::”以及sizeof運算符。(3)

只能對已定義了的運算符進行重載,而且當重載一個運算符時,該運算符的運算元個數(shù)、優(yōu)先順序和結(jié)合性是不能改變的。[例Ex_Complex]運算符的簡單重載。#include<iostream.h>classCComplex{ public: CComplex(doubler=0,doublei=0) { realPart=r; imagePart=i;}

voidprint() { cout<<"該複數(shù)實部=“<<realPart<<",虛部=“<<imagePart<<endl; } CComplexoperator+(CComplex&c);

CComplexoperator+(doubler);

private:

doublerealPart; doubleimagePart; };

CComplexCComplex::operator+(CComplex&c){ CComplextemp; temp.realPart=realPart+c.realPart; temp.imagePart=imagePart+c.imagePart; returntemp;}CComplexCComplex::operator+(doubler) { CComplextemp; temp.realPart=realPart+r; temp.imagePart=imagePart; returntemp;}voidmain(){ CComplexc1(12,20),c2(50,70),c; c=c1+c2; c.print(); c=c1+20; c.print();}

對運算符“+”作了兩次重載,一個用於實現(xiàn)兩個複數(shù)的加法,另一個用於實現(xiàn)一個複數(shù)與一個實數(shù)的加法。當重載一個運算符時,必須定義該運算符要完成的具體操作,而且當運算符重載函數(shù)是類的成員函數(shù)時,該函數(shù)的形參個數(shù)要比運算符運算元個數(shù)少一個,雙目運算符重載的成員函數(shù)只有一個參數(shù),單目運算符重載的成員函數(shù)沒有參數(shù)。

3.2運算符重載3.2.2賦值運算符的重載

對象的成員中有數(shù)組或動態(tài)的數(shù)據(jù)類型時,就不能直接相互賦值,否則在程式的編譯或執(zhí)行過程中出現(xiàn)編譯或運行錯誤。例如:

classCdemo { public:

CDemo(char*s) { ps=newchar[strlen(s)+1]; strcpy(ps,s); }

~CDemo() { if(ps)delete[]ps; } voidprint() {

cout<<ps<<endl; } private: char*ps; };

voidmain(){ CDemod1("Key"),d2("Mouse"); d1=d2; }

程式運行到“d1=d2”時發(fā)生運行錯誤。因此,必須重載“=”運算符,它與其他運算符的重載相同。

3.2運算符重載[例Ex_Evaluate]賦值運算符的重載。#include<iostream.h>#include<string.h>classCDemo{ public: //同上面的相同部分代省略

CDemo&operator=(CDemo&a) { if(ps)delete[]ps; if(a.ps){ ps=newchar[strlen(a.ps)+1]; strcpy(ps,a.ps);} elseps=0; return*this; } private: char*ps; };voidmain(){ CDemod1("Key"),d2("Mouse"); d1=d2; d1.print(); }

運行結(jié)果為: Mouse賦值運算符不能重載為友元函數(shù),只能是一個非靜態(tài)成員函數(shù)。

3.2運算符重載3.2.3提取和插入運算符重載

C++允許用戶重載“>>”和“<<”運算符,以便用戶利用標準的輸入輸出流來輸入輸出自己定義的數(shù)據(jù)類型(包括類),實現(xiàn)對象的輸入輸出。 重載這兩個運算符時最好將重載聲明為類的友元函數(shù),以便訪問類中的私有成員。

友元重載的一般格式如下:

friend<函數(shù)類型>operator<重載的運算符>(<形參>) //單目

{…} friend<函數(shù)類型>operator<重載的運算符>(<形參1,形數(shù)2)//雙目

{…} 對於單目運算符的友元重載函數(shù),只有一個形參,形參類型可以是類的對象,可以是引用,這取決於不同的運算符。對於雙目運算符的友元重載函數(shù)來說,它有兩個形參,這兩個形參中必須有一個是類的對象。需要說明的是,=、()、[]和->運算符不能用友元來重載。

3.2運算符重載[例Ex_ExtractAndInsert]提取和插入運算符的重載。

#include<iostream.h> classCStudent { public: friendostream&operator<<(ostream&os,CStudent&stu); friendistream&operator>>(istream&is,CStudent&stu);

private: charstrName[10]; //姓名

charstrID[10]; //學號

floatfScore[3]; //三門成績

};ostream&operator<<(ostream&os,CStudent&stu){ os<<endl<<"學生資訊如下:"<<endl; os<<"姓名:"<<stu.strName<<endl; os<<"學號:"<<stu.strID<<endl; os<<"成績:"<<stu.fScore[0]<<",\t" <<stu.fScore[1]<<",\t" <<stu.fScore[2]<<endl; returnos;}istream&operator>>(istream&is,CStudent&stu){ cout<<"請輸入學生資訊"<<endl; cout<<"姓名:"; is>>stu.strName; cout<<"學號:"; is>>stu.strID; cout<<"三門成績:"; is>>stu.fScore[0]>>stu.fScore[1]>>stu.fScore[2]; returnis; }voidmain(){ CStudentone; cin>>one; cout<<one; }3.3輸入輸出流庫

3.3.1概述

輸入輸出操作是由“流”來處理的。數(shù)據(jù)從一個位置到另一個位置的流動抽象為“流”。當流被建立後就可以使用一些特定的操作從流中獲取數(shù)據(jù)或向流中添加數(shù)據(jù)。從流中獲取數(shù)據(jù)的操作稱為“提取”操作,向流中添加數(shù)據(jù)的操作稱為“插入”操作。

ios類提供對流狀態(tài)進行設(shè)置的功能,是虛基類,其他類都是從這個派生而來的。

streambuf不是ios類的派生類,在類ios中只是有一個指針成員,指向streambuf類的一個對象。streambuf類是用來為ios類及其派生類提供對數(shù)據(jù)的緩衝支持。itream和ostream類是ios的公有派生類,前者向流中插入數(shù)據(jù)的有關(guān)操作,後者從流中提取數(shù)據(jù)的有關(guān)操作。iostream類是itream和ostream類公有派生的。

四個預定義的標準流對象:cin、cout、cerr和clog。當用戶在程式中包含了頭檔“iostream.h”,編譯器調(diào)用相應(yīng)的構(gòu)造函數(shù),產(chǎn)生這四個標準流對象,用戶在程式中就可以直接使用它們了。其中,cin是istream類的對象,用處理標準輸入cout是ostream類的對象,用處理標準輸出。cerr和clog都是ostream類的對象,用來處理標準出錯資訊,並將資訊顯示在螢?zāi)簧稀T谶@四個標準流對象中,除了cerr不支持緩衝外,其餘三個都帶有緩衝區(qū)。標準流通常使用提取運算符“>>”和插入運算符“<<”來進行輸入輸出操作的,而且系統(tǒng)還會自動地完成數(shù)據(jù)類型的轉(zhuǎn)換。

3.3輸入輸出流庫3.3.2cout和cin輸出流(cout)

cout可以輸出一個整數(shù)、實數(shù)、字元及字串,cout中的插入符“<<”可以連續(xù)寫多個,每個後面可以跟一個要輸出的常量、變數(shù)、轉(zhuǎn)義序列符、對象以及運算式等。

(1)

width函數(shù) 格式:intwidth(); intwidth(int);

第一種格式用來獲取當前輸出數(shù)據(jù)時的寬度。另一種格式是用來設(shè)置當前輸出數(shù)據(jù)時的寬度。 (2)

precision函數(shù) 格式:intprecision(); intprecision(int);

這兩種格式分別用來獲取和設(shè)置當前浮點數(shù)的有效數(shù)字的個數(shù),第二種格式函數(shù)還將返回設(shè)置前的有效數(shù)字的個數(shù)。需要說明的是,C++默認的有效數(shù)字的個數(shù)為6。

(3)

fill函數(shù) 格式:charfill(); charfill(char);

這兩種格式分別用來獲取和設(shè)置當前寬度內(nèi)的填充字元,第二種格式函數(shù)還將返回設(shè)置前的填充字元。

3.3輸入輸出流庫輸入流(cin)

格式: cin>><運算式1>[>><運算式2>...]

提取符“>>”可以連續(xù)寫多個,每個後面跟一個運算式,該運算式通常是獲得輸入值的變數(shù)或?qū)ο蟆?/p>

intx1,x2,x3;cin>>x1>>x2>>x3;

要求用戶從鍵盤上輸入三個整數(shù)。輸入時,必須在三個數(shù)值之間加上一些空格來分隔,空格的個數(shù)不限,最後用回車鍵結(jié)束輸入;或者在每個數(shù)值之後按回車鍵。格式算子oct、dec和hex

格式算子oct、dec和hex能分別將輸入或輸出的數(shù)值轉(zhuǎn)換成八進制、十進位及十六進制。3.3輸入輸出流庫

輸入輸出過程中發(fā)現(xiàn)操作錯誤,流就會將發(fā)生的錯誤記錄下來。用戶可以使用錯誤檢測功能,檢測和查明錯誤發(fā)生的原因和性質(zhì),然後調(diào)用clear函數(shù)清除錯誤狀態(tài),使流能夠恢復處理。

在ios類中,定義了一個公有枚舉成員io_state來記錄各種錯誤的性質(zhì):

enumio_state{ goodbit =0x00, //正常

eofbit =0x01, //已達到檔尾

failbit =0x02, //操作失敗

badbit =0x04 //非法操作}; 在ios類中又定義了檢測上述流狀態(tài)的下列成員函數(shù):

int ios::rdstate(); //返回當前的流狀態(tài)

intios::bad(); //如果badbit位被置位,返回非0 void ios::clear(int); //清除錯誤狀態(tài)

intios::eof(); //返回非0表示提取操作已到檔尾

intios::fail(); //如果failbit位被置位,返回非0 int

ios::good

();//操作正常時,返回非0

floatres;charbuf[80];cin>>res; ints=cin.rdstate(); while(s) { cin.clear(); cin.getline(buf,80); cout<<"錯誤輸出"<<endl; cin>>res; s=cin.rdstate();

//cout<<"流的狀態(tài):"<<hex<<s<<endl;

}3.3輸入輸出流庫3.3.4使用輸入輸出成員函數(shù)

輸入操作的成員函數(shù)

數(shù)據(jù)的輸入/輸出可以分為三大類:字元類、字串和數(shù)據(jù)。

(1)使用get和getline函數(shù)

intget(); istream&get(char&rch); istream&get(char*pch,intnCount,chardelim='\n');

getline函數(shù)原型如下:

istream&getline(char*pch,intnCount,chardelim='\n'); (2)使用read函數(shù)

istream&read(char*pch,intnCount); istream&read(unsignedchar*puch,intnCount); istream&read(signedchar*psch,intnCount); read函數(shù)的這幾種形式都是從輸入流中讀取由nCount指定數(shù)目的位元組並將它們放在由pch或puch或psch指定的數(shù)組中。輸出操作的成員函數(shù)

ostream&put(charch); ostream&write(constchar*pch,intnCount); ostream&write(constunsignedchar*puch,intnCount); ostream&write(constsignedchar*psch,intnCount);3.3輸入輸出流庫3.3.5檔流概述

檔看作是由連續(xù)的字元的數(shù)據(jù)順序組成。根據(jù)檔中數(shù)據(jù)的組織方式,可分為文本檔和二進位檔。文本檔中每一個位元組用以存放一個字元的ASCII碼值,二進位檔是將數(shù)據(jù)用二進位形式存放在檔中。

一個檔指針總是和一個檔所關(guān)聯(lián)的,在檔每一次打開時,檔指針指向檔的開始,隨著對檔的處理,檔指針不斷地在檔中移動,並一直指向最新處理的字元(位元組)位置。檔處理方式,一種稱為檔的順序處理。另一種稱為檔的隨機處理,並指向所要處理的字元(位元組)位置。按照這兩種處理方式,可將檔相應(yīng)地稱為順序檔和隨機檔。3.3輸入輸出流庫3.3.6順序檔操作

檔的打開和關(guān)閉

聲明一個ifstream、ofstream或fstream類對象。

使用檔流類的成員函數(shù)打開或創(chuàng)建一個指定的檔,使得該檔與聲明的檔流對象聯(lián)繫起來,這樣對流對象的操作也就是對檔的操作。

ifstream、ofstream或fstream類構(gòu)造函數(shù)中總有一種原型和它的成員函數(shù)open功能相同。它們的函數(shù)原型如下:

ifstream(constchar*szName,intnMode=ios::in,intnProt=filebuf::openprot); voidifstream::open(constchar*szName,intnMode=ios::in,intnProt=filebuf::openprot);

ofstream(constchar*szName,intnMode=ios::out,intnProt=filebuf::openprot); voidofstream::open(constchar*szName,intnMode=ios::out,intnProt=filebuf::openprot);

fstream(constchar*szName,intnMode,intnProt=filebuf::openprot); voidfstream::open(constchar*szName,intnMode,intnProt=filebuf::openprot);3.3輸入輸出流庫檔的讀寫

[例Ex_File]將檔內(nèi)容保存在另一檔中,並將內(nèi)容顯示在螢?zāi)簧稀?/p>

#include<iostream.h> #include<fstream.h>

voidmain() { fstreamfile1; file1.open("Ex_DataFile.txt",ios::in); if(!file1) { cout<<"Ex_DataFile.txt不能打開!\n"; return;}

fstreamfile2; file2.open("Ex_DataFileBak.txt",ios::out|ios::trunc); if(!file2) { cout<<"Ex_DataFileBak.txt不能創(chuàng)建!\n"; file1.close(); return; }

charch; while(!file1.eof()) { file1.read(&ch,1); cout<<ch; file2.write(&ch,1); } file2.close(); file1.close();}3.3輸入輸出流庫3.3.7隨機檔操作 隨機檔可以在檔中來回移動檔指針,從而可以實現(xiàn)非順序讀寫檔數(shù)據(jù)的功能,達到快速檢索、修改和刪除檔數(shù)據(jù)的效果。

seekg和seekp函數(shù)將檔指針移動到指定的位置。它們的原型如下:

istream&seekg(longpos); istream&seekg(longoff,ios::seek_dirdir); ostream&seekp(longpos); ostream&seekp(longoff,ios::seek_dirdir);

其中,pos用來指定檔指針的絕對位置。若用off指定檔指針的相對偏移量時,檔指針的最終位置還需根據(jù)dir值才能確定。dir值可以是:

ios::beg 從檔流的頭部開始

ios::cur 從當前的檔指針位置開始

ios::end

從檔流的尾部開始

3.4範本

3.4.1函數(shù)重載機制的不足

函數(shù)重載方便用戶對函數(shù)名的記憶,完善了同一個函數(shù)的代碼功能。允許多個同名的函數(shù)存在,同名的各個函數(shù)的形參必須有區(qū)別:形參的個數(shù)不同,或者形參的個數(shù)相同,但形參類型有所不同。 如果需要處理所有標準數(shù)據(jù)類型的參數(shù),則還需要更多的代碼進行函數(shù)重載??梢钥闯龊瘮?shù)重載有時也顯得比較煩瑣,解決這個問題就是使用函數(shù)範本。3.4.2函數(shù)範本

格式:

template<數(shù)據(jù)類型聲明>

函數(shù)體

template是一個聲明範本的關(guān)鍵字,數(shù)據(jù)類型聲明是使用class關(guān)鍵字來定義類型名稱,而函數(shù)體與傳統(tǒng)的函數(shù)定義相似。3.4範本[例Ex_FunTemplate]使用函數(shù)範本。

#include<iostream.h> template<classT> Tsum(Tx,Ty,Tz) { returnx+y+z; }

template<classT,classT1> //定義第二個函數(shù)範本

Tsum(Tx,T1y) { returnx+y; }

voidmain() { cout<<sum(2,'a')<<endl; cout<<sum('a',2)<<endl; cout<<sum(2,5,7)<<endl; cout<<sum(1.2,5.0,7.5)<<endl; }

3.4範本3.4.3類範本

template<數(shù)據(jù)類型聲明>class類名

{ ... //成員的定義

}; 注意:大括弧後的分號不能省略。3.4.4標準範本庫簡介

標準範本庫STL(StandardTemplateLibrary)是通過STL中的相應(yīng)運算法則在應(yīng)用程式的迭代子(iterator)、容器以及其他定義的序列中建立一種統(tǒng)一的標準。從根本上來說,STL是一個基於範本的群體類庫,它包含群體類(鏈表或列表、向量、棧、佇列、集合、映象)、演算法(排序、查找)以及迭代子。

STL中的群體類是基於範本的,包含線性群體類,也包含非線性群體類。其主要群體類有:

deque(雙端佇列) list(鏈表、列表) map(映象) multimap(多重映象)

multiset(多重集合) set(集合) vector(向量)3.4範本

STL的迭代子有順序和直接訪問,順序迭代子使用++、--等進行指針移動,只能順序訪問群體類中的對象,而直接訪問迭代子是通過iterator_traits來直接訪問群體類中的某個特定對象。iterator_traits用來指定要訪問的屬性類型,它可以有:

iterator_category(目錄類型) value_type(數(shù)值類型) difference_type(距離類型,表示兩個指針的地址之間的距離) pointer(指針類型) reference(引用類型)

STL的演算法是用函數(shù)範本實現(xiàn)的,可以實現(xiàn)對不同類型對象的通用操作。演算法與STL群體類之間是通過迭代子iterator來進行溝通的。STL的主要演算法有: 排序(sort、merge)

查找(find、search)

比較(equal)

集合(includes、set_union、set_difference)

計算(accumulate、partial_sum)

統(tǒng)計(max、min)

管理(swap、fill、replace、copy、unique、rotate、reverse)

堆操作(make_heap、push_heap、pop_heap、sort_heap)

對話框

4.1從C++到Windows編程

4.1.1簡單的Windows應(yīng)用程式

[例Ex_HelloMsg]一個最簡單的Windows應(yīng)用程式。

(1)選擇“檔”

“新建”菜單命令,顯示出“新建”對話框。單擊“工程”標籤,從列表框中選中Win32Application(Win32應(yīng)用程式)項。

(2)在工程名稱框中鍵入Win32應(yīng)用程式專案名稱Ex_HelloMsg。在“位置”下的編輯框中直接鍵入檔夾名稱,或單擊流覽按鈕(...)選擇一個已有的檔夾。

(3)單擊[確定]按鈕繼續(xù)。一個詢問專案類型的Win32應(yīng)用程式嚮導將被顯示,選中Anemptyproject項。單擊[完成]按鈕,系統(tǒng)將顯示AppWizard的創(chuàng)建資訊,單擊[確定]按鈕系統(tǒng)將自動創(chuàng)建此應(yīng)用程式。

4.1從C++到Windows編程(4)再次選擇“檔”

“新建”菜單命令,顯示出“新建”對話框。單擊“檔”標籤,在左邊的列表框中選擇C++SourceFile項,在右邊的“檔”下的編輯框中鍵入Ex_HelloMsg.cpp,單擊[確定]按鈕。

(5)

輸入下麵的代碼:

#include<windows.h> intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow) { MessageBox(NULL,"你好,我的VisualC++世界!","問候",0);return0; }4.1從C++到Windows編程

WinMain函數(shù)的原型如下:

intWINAPIWinMain( HINSTANCEhInstance, //當前實例句柄

HINSTANCEhPrevInstance, //前一實例句柄

LPSTRlpCmdLine, //指向命令行參數(shù)的指針

intnCmdShow) //窗口的顯示狀態(tài) 這裏出現(xiàn)了一個新的概念——“句柄”(handle),所謂句柄是一個標識Windows資源和設(shè)備等對象的變數(shù),或者是一個對操作系統(tǒng)資源的間接引用。每一個用C/C++編寫的Windows應(yīng)用程式都需要Windows.h頭檔,它還包含了其他的一些Windows頭檔。這些頭檔定義了Windows的所有數(shù)據(jù)類型、函數(shù)調(diào)用、數(shù)據(jù)結(jié)構(gòu)和符號常量。程式中,MessageBox是一個Win32API(ApplicationProgrammingInterface,應(yīng)用程式介面)函數(shù),用來彈出一個對話框窗口,顯示短資訊。該函數(shù)第一個參數(shù)用來指定父窗口句柄,即對話框所在的窗口句柄。第二、三個參數(shù)分別用來指定顯示的消息內(nèi)容和對話框窗口的標題,最後一個參數(shù)用來指定在對話框中顯示的按鈕。

4.1從C++到Windows編程4.1.2Windows編程特點

Windows應(yīng)用程式具有這樣的一些特性:消息驅(qū)動機制、圖形設(shè)備介面(GDI)、基於資源的程式設(shè)計、動態(tài)鏈接庫。消息驅(qū)動機制

DOS程式是通過調(diào)用系統(tǒng)的函數(shù)來獲得用戶輸入的,Windows程式是通過操作系統(tǒng)發(fā)送的消息來處理用戶輸入的。消息驅(qū)動的機制是Windows編程的最大特點。

WinMain函數(shù)通常要完成以下幾步工作:

定義並調(diào)用API函數(shù)RegisterClass註冊應(yīng)用程式的窗口類。

調(diào)用相關(guān)API函數(shù)創(chuàng)建和顯示窗口,並進行其他必要的初始化處理。其中,函數(shù)CreateWindow用來創(chuàng)建已註冊窗口類的窗口。創(chuàng)建和啟動應(yīng)用程式的消息迴圈。Windows應(yīng)用程式接受各種不同的消息,包括鍵盤消息、滑鼠以及窗口產(chǎn)生的各種消息。Windows系統(tǒng)首先將消息放入消息佇列中,應(yīng)用程式的消息迴圈就是從應(yīng)用程式的消息佇列中檢取消息,並將消息發(fā)送相應(yīng)的窗口過程函數(shù)中作進一步處理。API函數(shù)GetMessage和DispatchMessage就是起到這樣的作用。如果接收到WM_QUIT消息,則退出應(yīng)用程式。4.1從C++到Windows編程圖形設(shè)備介面(GDI)

Windows提供了一個抽象的圖形設(shè)備介面(GraphicalDeviceInterface,簡稱GDI),使用戶直接利用系統(tǒng)的GDI函數(shù)就能方便實現(xiàn)圖形和文本的輸出,而不必關(guān)心與系統(tǒng)相連的外部設(shè)備的類型。

基於資源的程式設(shè)計

Windows應(yīng)用程式常常包含眾多圖形元素。每一個這樣的資源都用相應(yīng)的識別字來區(qū)分,而且Windows內(nèi)部也有預定義的資源。在Windows環(huán)境下,每一個資源元素都作為一種可以裝入應(yīng)用程式的資源來存放。這些資源可以被編輯、修改,也可以被其他應(yīng)用程式所共用。動態(tài)鏈接庫

動態(tài)鏈接庫提供一些特定結(jié)構(gòu)的函數(shù),能被應(yīng)用程式在運行過程中裝入和連接,且多個程式可以共用同一個動態(tài)鏈接庫。

Windows提供了應(yīng)用程式可調(diào)用的豐富的函數(shù),大多數(shù)用於實現(xiàn)其用戶介面和在顯示器上顯示的文本和圖形,都是通過動態(tài)鏈接庫來實現(xiàn)的。這些動態(tài)鏈接庫是一些具有DLL擴展名或者有時是EXE擴展名的檔。在Windows操作系統(tǒng)中,最主要的DLL有KERNEL32.DLL、GDI32.DLL和USER32.DLL。其中,KERNEL32.DLL用來處理記憶體低層功能、任務(wù)和資源管理等Windows核心服務(wù);GDI32.DLL用來提供圖形設(shè)備介面,管理用戶介面和圖形繪製,包括Windows元檔、位圖、設(shè)備描述表和字體等;而USER32.DLL負責窗口的管理,包括消息、菜單、游標、計時器以及其他與控制窗口顯示相關(guān)的一些功能。4.1從C++到Windows編程4.1.3Windows基本數(shù)據(jù)類型

4.1從C++到Windows編程4.1.4MFC應(yīng)用程式框架類型

MFC把編程規(guī)範中的大多數(shù)內(nèi)容封裝成為各種類,使程式員從繁雜的編程中解脫出來。VisualC++還提供大量的嚮導和可視化編輯工具,使得用戶不需要添加太多的代碼就能實現(xiàn)不同風格和用途的應(yīng)用程式。

MFCAppWizard就是VisualC++6.0提供的一個非常有用的嚮導,它能為用戶快速、高效、自動地生成一些常用的標準程式結(jié)構(gòu)和編程風格。

MFCAppWizard(exe)應(yīng)用程式框架包含用戶最常用、最基本的三種應(yīng)用程式類型:單文檔、多文檔和基於對話框的應(yīng)用程式。單文檔應(yīng)用程式每次只能打開和處理一個文檔對話框的程式?jīng)]有菜單、工具欄及狀態(tài)欄,也不能處理文檔,但它的好處是速度快,代碼少,程式員所花費的開發(fā)和調(diào)試時間短。多文檔應(yīng)用程式,能允許同時打開和處理多個文檔。與單文檔應(yīng)用程式相比,增加了許多功能,因而需要大量額外的編程工作。4.1從C++到Windows編程表4.2MFCAppWizard創(chuàng)建的應(yīng)用程式類型

4.1從C++到Windows編程4.1.5創(chuàng)建一個應(yīng)用程式框架

[例Ex_SDI]創(chuàng)建一個默認的單文檔應(yīng)用程式。

開始 選擇“檔”

“新建”菜單,在彈出的“新建”對話框中選擇“工程”標籤,這時顯示出一系列的應(yīng)用程式專案類型;選擇MFCAppWizard(exe)的專案類型(該類型用於創(chuàng)建可執(zhí)行的Windows應(yīng)用程式),將專案工作檔夾定位在“…\VisualC++6.0程式\對話框”,並在工程框中輸入專案名Ex_SDI。

4.1從C++到Windows編程選擇程式類型 單擊[確定]按鈕,進行下列選擇:(1)

從應(yīng)用程式類型單個文檔(SingleDocument,簡稱SDI)、多重文檔(MultipleDocument,簡稱MDI)和基本對話(DialogBased,基於對話框的應(yīng)用程式)中選擇“單個文檔”。(2)

決定應(yīng)用程式中是否需要MFC的文檔視圖(“文檔/查看體系結(jié)構(gòu)支持”)結(jié)構(gòu)的支持。若不選定此項,則程式中的磁片檔的打開、保存以及文檔和視圖的相互作用等功能需要用戶來實現(xiàn)。一般情況下,應(yīng)選中此項。(3)選擇資源所使用的語言,這裏是“中文[中國]”。4.1從C++到Windows編程簡單創(chuàng)建

保留默認的選項,單擊[完成]按鈕,顯示出用戶在步驟中作出的選擇,單擊[確定]按鈕系統(tǒng)開始創(chuàng)建。

4.1從C++到Windows編程編譯並運行

到這裏為止,用戶雖然沒有編寫任何程式代碼,但MFCAppWizard已經(jīng)根據(jù)用戶的選擇內(nèi)容自動生成基本的應(yīng)用程式框架。單擊編譯工具條 上的運行工具按鈕“”或按快捷鍵Ctrl+F5,系統(tǒng)開始編連並運行生成的單文檔應(yīng)用程式可執(zhí)行檔Ex_SDI.exe。

4.2添加並使用對話框

4.2.1資源與資源標識

資源的分類

將上例Ex_SDI的專案工作區(qū)窗口切換到“ResourceView”頁面。

資源可分為下列幾類:

(1)快捷鍵列表(Accelerator):一系列組合鍵的集合,被應(yīng)用程式用來引發(fā)一個動作。該列表一般與菜單命令相關(guān)聯(lián),用來代替滑鼠操作。

(2)對話框(Dialog):含有按鈕、列表框、編輯框等各種控件的窗口。

(3)圖示(Icon):代表應(yīng)用程式顯示在Windows桌面上的位圖,它同時有32

32像素和16

16像素兩種規(guī)格。

(4)菜單(Menu):用戶通過菜單可完成應(yīng)用程式的大部分操作。 (5)字串表(StringTable):應(yīng)用程式使用的全局字串或其他識別字。

(6)工具欄按鈕(Toolbar):工具欄外觀是以一系列具有相同尺寸的位圖組成的,它通常與一些菜單命令項相對應(yīng),用以提高用戶的工作效率。

(7)版本資訊(Version):包含應(yīng)用程式的版本、用戶註冊碼等相關(guān)資訊。

4.2添加並使用對話框識別字

每一個資源類別下都有一個或多個相關(guān)資源,每一個資源均是由識別字來定義的。當添加或創(chuàng)建一個新的資源或資源對象時,系統(tǒng)會為其提供默認的名稱,如IDR_MAINFRAME等。用戶可重新命名,但要按一定的規(guī)則來進行。一般地,要遵循下列規(guī)則:

(1)

在識別字名稱中允許使用字母a~z、A~Z、0~9以及下劃線。

(2)

識別字名稱不區(qū)分大小寫字母,如new_idd與New_Idd是相同的識別字。

(3)

不能以數(shù)字開頭,如8BIT是不合法的識別字名。

(4)

字元個數(shù)不得超過247個。4.2添加並使用對話框4.2.2添加對話框資源

添加對話框資源一般可按下列步驟(在上例Ex_SDI基礎(chǔ)上進行):

(1)選擇“插入”

“資源”菜單,或按快捷鍵Ctrl+R打開“插入資源”對話框,在對話框中可以看到資源列表中存在Dialog項,若單擊Dialog項左邊的“+”號,將展開對話框資源的不同類型選項。

4.2添加並使用對話框

(2)對展開的不同類型的對話框資源不作任何選擇,選中“Dialog”,單擊[新建]按鈕,系統(tǒng)就會自動為當前應(yīng)用程式添加了一個對話框資源。

系統(tǒng)為對話框資源自動賦給它一個默認的識別字名稱(第一次為IDD_DIALOG1,以後依次為IDD_DIALOG2、IDD_DIALOG3、...)。使用通用的對話框範本創(chuàng)建新的對話框資源。對話框的默認標題為Dialog,有[OK]和[Cancel]兩個按鈕,這兩個按鈕的識別字分別為IDOK和IDCANCEL。對話框範本資源所在的窗口稱為對話框資源編輯器,在這裏可以通過控件工具欄和佈局工具欄向?qū)υ捒蛱砑雍蛠丫挚丶?,並可設(shè)置對話框的屬性。4.2添加並使用對話框4.2.3設(shè)置對話框?qū)傩?/p>

在對話框範本處右擊滑鼠,從彈出的快捷菜單中選擇“屬性”菜單項。

表4.5對話框的General屬性

4.2添加並使用對話框?qū)⑻砑拥膶υ捒虻膶傩赃M行如下三點修改:將對話框識別字改成IDD_DIALOG_FIRST;

將對話框標題改為“我的第一個對話框”;單擊[字體]按鈕,通過彈出的字體對話框?qū)υ捒騼?nèi)的文本設(shè)置成“宋體,9”

,以使自己的對話框和Windows中的對話框保持外觀上的一致。

4.2添加並使用對話框4.2.4添加和佈局控件 在對話框中添加一個控件的方法:在控件工具欄中單擊某控件;在對話框指定位置單擊滑鼠左鍵,則此控件被添加到對話框的相應(yīng)位置,再拖動選擇框可改變控件的大小和位置。在控件工具欄中單擊某控件,此時的滑鼠箭頭對話框內(nèi)變成“十”字形狀;在指定位置處單擊滑鼠左鍵不放,拖動滑鼠至滿意位置,釋放滑鼠鍵。用滑鼠左鍵點中控件工具欄中的某控件,並按住滑鼠左鍵不放;在移動滑鼠到對話框的指定位置的過程中,用戶會看到一個虛線框,下麵帶有該控件的標記;釋放滑鼠左鍵,新添加的控件立即出現(xiàn)在對話框中。

控件的選擇靜態(tài)文本組框複選框組合框水準滾動條旋轉(zhuǎn)按鈕滑動條列表視圖標籤複合編輯月曆用戶定制工具靜態(tài)圖片編輯框按鈕單選框列表框垂直滾動條進展條熱鍵樹形視圖動畫日期選擇IP地址組合框的擴展圖4.14控件工具欄和各按鈕含義4.2添加並使用對話框控件的選取

選取單個控件,則可以下列方法。用滑鼠直接選取。用助記符來選取。用Tab鍵選取。對於多個控件的選取,可採用下列方法:先在對話框內(nèi)按住滑鼠左鍵不放,拖出一個大的虛框,然後釋放滑鼠,則被該虛框所包圍的控件都將被選取。先按住Shift鍵不放,然後用滑鼠選取控件,直到所需要的多個控件選取之後再釋放Shift鍵。若在選取時,對已選取的控件再選取一下,則取消該控件選取。需要注意的是:(1)

一旦單個控件被選取後,其四周由選擇框包圍著,選擇框上還有幾個(通常是八個)藍色實心小方塊,拖動它可改變控件的大小。(2)多個控件被選取後,其中只有一個控件的選擇框有幾個藍色實心小方塊,這個控件稱為主要控件,而其他控件的選擇框的小方塊是空心的。(b)圖4.15單個控件和多個控件的選擇框(a)4.2添加並使用對話框控件的刪除、複製和佈局

與佈局工具相對應(yīng)的菜單命令在“編排”菜單下,而且大部分命令均有相應(yīng)的快捷鍵

圖4.17“編排”菜單命令項4.2添加並使用對話框注意:大多數(shù)佈置控件的命令使用前,都需要用戶選取多個控件,且“主要控件”起到了關(guān)鍵作用。例如用戶選取多個控件後,使用“MakeSameSize”命令只改變其他控件的大小,並與“主要控件”的尺寸一致。因此,在多個控件的佈置過程中,常需要重新設(shè)置“主要控件”。設(shè)置的方法是按住Ctrl或Shift鍵,然後用滑鼠單擊所要指定的控件即可。為了便於用戶在對話框內(nèi)精確定位各個控件,系統(tǒng)還提供了網(wǎng)格、尺規(guī)等輔助工具。在圖4.16的控件佈局工具欄的最後兩個按鈕分別用來網(wǎng)格和尺規(guī)的切換。一旦網(wǎng)格顯示,添加或移動控件時都將自動定位在網(wǎng)格線上。

表4.6“編排”菜單命令的快捷鍵及功能描述

4.2添加並使用對話框測試對話框

“編排”菜單下的Test命令或佈局工具欄上的測試按鈕是用來模擬所編輯的對話框的運行情況,幫助用戶檢驗對話框是否符合用戶的設(shè)計要求以及控件功能是否有效等。

操作示例

向?qū)υ捒蛱砑右粋€靜態(tài)文本控件。一個靜態(tài)文本控件就是一個文本標籤。 右擊添加的控件,從彈出的快捷菜單中選擇“屬性”。

4.2添加並使用對話框4.2.5創(chuàng)建對話框類

在對話框資源範本的空白區(qū)域內(nèi)雙擊滑鼠,彈出對話框,詢問是否為對話框資源創(chuàng)建一個新類。單擊[OK]按鈕,彈出NewClass對話框。Name框是用來輸入用戶定義的類名,單擊[Change]按鈕可改變默認的原始檔案名稱及其在磁片中的位置。從Baseclass框的內(nèi)容看出,用戶對話框類是從基類CDialog派生而來的。在Name框中輸入類名CFirstDlg,單擊[O

溫馨提示

  • 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

提交評論