版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1VC++面向?qū)ο笈c可視化程序設(shè)計(jì)清華大學(xué)計(jì)算機(jī)系2第1章C++基礎(chǔ)知識(shí)31.1關(guān)于C++ C++是既適合于作為系統(tǒng)描述語(yǔ)言,也適合于編寫(xiě)應(yīng)用軟件的既面向?qū)ο笥置嫦蜻^(guò)程的一種混合型程序設(shè)計(jì)語(yǔ)言,它是在C語(yǔ)言的基礎(chǔ)之上發(fā)展起來(lái)的。1.2一個(gè)簡(jiǎn)單的C++程序4一個(gè)簡(jiǎn)單的C++程序
下面通過(guò)一個(gè)非常簡(jiǎn)單的用C++編寫(xiě)的例子,讓讀者了解一下C++的基本輸出操作。其功能是在屏幕上顯示“Welcome!”,其程序代碼如下:#include"iostream"usingnamespacestd;intmain() //main函數(shù),程序入口{ charstr_greet[]="Welcome!";//定義一個(gè)數(shù)組并初始化 cout<<str_greet<<endl; //在屏幕上輸出字符串內(nèi)容return0;} 創(chuàng)建基于空項(xiàng)目的C++應(yīng)用程序C/C++編寫(xiě)的程序在程序結(jié)構(gòu)上基本是相同的,都是以main為入口;不同:C++以iostream作為標(biāo)準(zhǔn)IO頭文件,C以stdio.h作為標(biāo)準(zhǔn)IO頭文件;C++中采用“<<”作為標(biāo)準(zhǔn)輸出,C是用printf來(lái)實(shí)現(xiàn)。6cout是C++中的標(biāo)準(zhǔn)輸出流(通常為控制臺(tái),即屏幕),這句話把一串字符串(本例中為“Welcome!”)插入輸出流(控制臺(tái)輸出)中。cout在聲明在頭文件iostream中,所以要想使用cout必須將該頭文件包括在程序開(kāi)始處。早些的實(shí)現(xiàn)將標(biāo)準(zhǔn)庫(kù)功能定義在全局空間里,聲明在帶.h后綴的頭文件里,c++標(biāo)準(zhǔn)為了和C區(qū)別開(kāi),也為了正確使用命名空間,規(guī)定頭文件不使用后綴.h。使用.h,相當(dāng)于在c中調(diào)用庫(kù)函數(shù),使用的是全局命名空間,也就是早期的c++實(shí)現(xiàn);當(dāng)使用<iostream>的時(shí)候,該頭文件沒(méi)有定義全局命名空間,必須使用namespacestd;這樣才能正確使用cout。7namespace是指標(biāo)識(shí)符的各種可見(jiàn)范圍。C++標(biāo)準(zhǔn)程序庫(kù)中的所有標(biāo)識(shí)符都被定義于一個(gè)名為std的namespace中。使用方法是:命名空間std封裝的是標(biāo)準(zhǔn)函數(shù)庫(kù)的名稱,標(biāo)準(zhǔn)函數(shù)庫(kù)為了和以前的頭文件區(qū)別,一般不加".h"
usingnamespacestd;1.3C++中的變量和數(shù)據(jù)類型81.3.1變量的初始化(1)數(shù)字值變量的初始化在C++中,數(shù)值變量的初始化可以在括號(hào)內(nèi)進(jìn)行,其格式如下:數(shù)據(jù)類型變量名(初值);比如下面的例子中,語(yǔ)句“intb(10);”就是這種定義模式。#include<iostream>usingnamespacestd;intmain(){inta=3; //初始值為3intb(10); //初始值為10intresult; //不確定初始值result=a-b;cout<<result;return0;} 9(2)非數(shù)字值變量的初始化針對(duì)字符串,C++提供一個(gè)string類來(lái)支持字符串的操作,該類并不是一個(gè)基本的數(shù)據(jù)類型,但在一般的使用中與基本數(shù)據(jù)類型很相似。用戶如果需要聲明和使用字符串類型的變量,需要引用頭文件<string>,如下面例子所示:#include<iostream>#include<string>usingnamespacestd;intmain(){stringtest_string;test_string="TestString***China***";cout<<test_string<<endl;test_string="TestString***Beijing***";cout<<test_string<<endl;return0;} 10(3)常量的初始化C++通過(guò)使用const關(guān)鍵字來(lái)完成常量定義的:constintx=5;constchary='n';111.3.2C++的輸入與輸出操作(1)輸入操作C++中的標(biāo)準(zhǔn)輸入是采用“cin>>”這個(gè)格式來(lái)完成。它后面必須跟一個(gè)變量以便存儲(chǔ)讀入的數(shù)據(jù)。例如:intx; //聲明一個(gè)整型變量xcin>>x; //將輸入值存儲(chǔ)在這個(gè)變量x中
也可以利用cin輸入多個(gè)數(shù)據(jù),如:cin>>x>>y;等同于:cin>>x;cin>>y;
在以上兩種情況下用戶都必須輸入兩個(gè)數(shù)據(jù),分別給變量x和y。輸入時(shí)兩個(gè)變量之間可以使用空格符、tab符或回車。12
值得注意的是,使用cin和>>操作符來(lái)讀取字符串,例如:cin>>test_string;
由于“cin>>”只能讀取一個(gè)單詞,一旦碰到任何空格,讀取操作就會(huì)停止,這樣就無(wú)法輸入一個(gè)英文句子,要解決此問(wèn)題,可以使用C++的getline函數(shù),對(duì)于字符串的讀入,更建議使用getline來(lái)進(jìn)行。
13下面是一個(gè)讀取字符串的例子:#include<iostream>#include<string>usingnamespacestd;intmain(){stringtest_string;cout<<"你在哪個(gè)學(xué)校上學(xué)?";getline(cin,test_string);cout<<"Hello"<<test_string<<"\n";cout<<"你喜歡什么專業(yè)?";
getline(cin,test_string);cout<<"我喜歡"<<test_string<<"專業(yè)\n";return0;}改成cin>>test_string;試試看(2)輸出操作
輸出用“<<”進(jìn)行操作,比如:cout<<"Hello!"<<"VC++"<<"ObjectOrientedProgramming";初學(xué)者要注意輸出字符串和輸出變量的區(qū)別。請(qǐng)觀察如下的代碼:cout<<"abc"; //打印字符串a(chǎn)bc到屏幕上cout<<abc; //把變量abc存儲(chǔ)的內(nèi)容輸出到屏幕上
15上面這一行語(yǔ)句將會(huì)打印
Hello!VC++ObjectOrientedProgramm
到屏幕上。值得注意的是,cout操作不會(huì)產(chǎn)生換行,因此,當(dāng)需要換行的時(shí)候,可以輸出一個(gè)換行符“\n”,如:cout<<"Hello!\n";此外還可以用操作符endl來(lái)?yè)Q行,例如:cout<<"Hello!"<<endl;cout<<"VisualC++"<<endl;將會(huì)輸出:Hello!.VisualC++(3)C++中的輸入輸出流C++中把數(shù)據(jù)之間的傳輸操作抽象地稱作流。在C++中,流可以表示數(shù)據(jù)從內(nèi)存?zhèn)魉偷侥硞€(gè)載體或者設(shè)備中,叫做輸出流;也可以表示數(shù)據(jù)從某個(gè)載體或者設(shè)備傳送到內(nèi)存緩沖區(qū)變量中,叫做輸入流。數(shù)據(jù)在不同的設(shè)備之間傳送后不一定會(huì)消失,廣義地講,也可以把與數(shù)據(jù)傳送有關(guān)系的事務(wù)叫做流,例如,可以把文件變量叫做流,有時(shí)候,流還可以代表要進(jìn)行傳送的數(shù)據(jù)的結(jié)構(gòu)、屬性和特性,用一個(gè)名字來(lái)表示,叫做流類;而用流代表輸入設(shè)備和輸出設(shè)備,叫作流的對(duì)象。17(a)輸出流cout在C++中預(yù)先定義了一個(gè)輸出流的成員函數(shù)put,其用法如下:cout.put(charch)或cout.out(constcharch)下面的代碼,體現(xiàn)put函數(shù)的應(yīng)用://#include"stdafx.h"#include<iostream>usingnamespacestd;intmain(){charch1='M',ch2='N';cout<<'M'<<'.'<<'N'<<endl;cout.put(ch1).put('.').put(ch2).put('\n');cout.put('M').put('.').put('N').put('\n');return0;}上述代碼的輸出結(jié)果是三個(gè)M.N,值得說(shuō)明的是,cout對(duì)象可以連續(xù)調(diào)用put函數(shù),比如代碼:cout.put(ch1).put('.').put(ch2).put('\n');cout.put('M').put('.').put('N').put('\n');就是連續(xù)調(diào)用了put函數(shù)。18我們還可以使用write()函數(shù)輸出字符串,其函數(shù)調(diào)用格式如下:cout.write(constchar*str,intn)其中參數(shù)str是指向字符對(duì)象的指針,參數(shù)n表示要輸出的字符對(duì)象的字節(jié)數(shù)。下面通過(guò)一個(gè)簡(jiǎn)單的例子介紹write()函數(shù)的應(yīng)用。#include<iostream>usingnamespacestd;intmain(){charstr1[]="ABCDEFGHIJ";charstr2[]="abcdefghij";cout.write(str1,10).put('\n');cout.write(str2,strlen(str2)).put('\n');cout.write("HELLOWORLD",5)<<endl;return0;}從cout.write("HELLOWORLD",5)<<endl;可以看出,利用write()函數(shù)可實(shí)現(xiàn)對(duì)字符串的部分或全部的輸出,而其中的第一個(gè)參數(shù),既可以是指向字符對(duì)象的指針,也可以是字符型數(shù)組的首地址(數(shù)組名),也可以直接給出字符串常量,用起來(lái)還是很方便的。19其輸出結(jié)果為:ABCDEFGHIJabcdefghijHELLO(b)輸入流cin
在C++的標(biāo)準(zhǔn)輸入流中,可以使用cin的成員函數(shù)get()、getline()和read()等。下面介紹get()函數(shù)的使用,請(qǐng)參見(jiàn)下面的代碼:#include<iostream>usingnamespacestd;intmain(){intn=0;charch;cout<<"請(qǐng)輸入一個(gè)字符串:\n";while((ch=cin.get())!='\n'){cout<<ch;n++;}cout<<"\n總字符個(gè)數(shù)是"<<n<<endl;return0;}20
當(dāng)cin被用來(lái)輸入字符串時(shí),常與函數(shù)getline一起使用:cin.getline(charbuffer[],intlength,chardelimiter='\n');其中:buffer:用來(lái)存儲(chǔ)輸入的地址。函數(shù)是從當(dāng)前的流開(kāi)始,讀取size-1個(gè)字符,或者是遇到delim指定的分隔符就結(jié)束;length:一個(gè)緩存buffer的最大容量;delimiter:用來(lái)判斷用戶輸入結(jié)束的字符,它的默認(rèn)值是換行符('\n')。21下面的例子顯示了如何使用cin.getline來(lái)輸入字符串:#include<iostream>usingnamespacestd;intmain(){charstr[50];cout<<"你在哪一所學(xué)校?";cin.getline(str,50);cout<<"Hello"<<str<<".\n";cout<<"你學(xué)什么專業(yè)?";cin.getline(str,50);cout<<"我喜歡"<<str<<"專業(yè)\n";return0;}下面的代碼展現(xiàn)其應(yīng)用:#include<iostream>usingnamespacestd;intmain(){charch[30];cout<<"請(qǐng)輸入一個(gè)字符串:\n";cin>>ch;cout<<"所輸入的字符串是"<<ch<<endl;
cin.getline(ch,30,'!');cout<<"遇!之前的字符是:"<<ch<<endl;
cin.getline(ch,30);cout<<"遇!之后的字符是"<<ch<<endl;return0;}請(qǐng)輸入一個(gè)字符串:HelloVisual!C++所輸入的字符串是Hello遇!之前的字符是:Visual遇!之后的字符是C++
值得注意的是,對(duì)于cin的輸入,它在提取數(shù)據(jù)時(shí),遇到第一個(gè)空格就會(huì)停止,因此,第一個(gè)輸出是“Hello”,然后第二個(gè)輸出語(yǔ)句,從當(dāng)前的結(jié)束位置繼續(xù)往后讀取,當(dāng)遇到“!”時(shí)結(jié)束,于是就輸出“Visual”,最后剩下的輸出語(yǔ)句,就輸出剩下的字符串,一直到回車結(jié)束,或29個(gè)字符為止,于是就輸出“C++”。如下面的代碼用的是“!”標(biāo)識(shí)結(jié)束,函數(shù)把讀取的字符串寫(xiě)入buf地址開(kāi)始的一段連續(xù)存儲(chǔ)空間,并在結(jié)束位置自動(dòng)加上截止符“\0”。read()函數(shù)的用法很簡(jiǎn)單,其原型如下:cin.read(c,count);
其功能是從字符串流中讀取count個(gè)字符到c數(shù)組中。下面舉個(gè)簡(jiǎn)單的例子說(shuō)明其應(yīng)用。#include<iostream>usingnamespacestd;intmain(){charc[10];intcount=3;cout<<"請(qǐng)輸入一個(gè)字符串\n";
cin.read(c,count);c[count]='\0';cout<<c<<endl;cout<<c[count+1]<<endl;return0;}上述代碼中從讀入的字符串中提取前三個(gè)字符并輸出。23(3)字符串流
標(biāo)準(zhǔn)頭文件<sstream>定義了一個(gè)叫做stringstream的類,使用這個(gè)類可以對(duì)基于字符串的對(duì)象進(jìn)行操作,這對(duì)將字符串與數(shù)值互相轉(zhuǎn)換非常有用。例如,如果我們想將一個(gè)字符串轉(zhuǎn)換為一個(gè)整數(shù),可以這樣寫(xiě):#include<sstream>stringmy_string("12345");intmy_int;stringstream(my_string)>>my_int;cout<<my_int;
上述代碼定義了一個(gè)字符串類型的對(duì)象my_string,并賦初值為"12345",然后接著定義了整型變量my_int,最后調(diào)用stringstream類的構(gòu)造函數(shù),并以字符串變量my_string為參數(shù)。這段代碼執(zhí)行之后變量my_int存儲(chǔ)的是數(shù)值12345。24下面是一個(gè)完整的實(shí)例體驗(yàn)此應(yīng)用。#include<iostream>#include<sstream>usingnamespacestd;intmain(){stringstr;floata=0.0;intb=0;cout<<"a=?";getline(cin,str);stringstream(str)>>a;cout<<"b=?";getline(cin,str);stringstream(str)>>b;cout<<"a*b="<<a*b<<endl;return0;}25在此代碼的執(zhí)行過(guò)程中,輸入了變量a和b的值。但不同于從標(biāo)準(zhǔn)輸入中直接讀取數(shù)值,這里使用函數(shù)getline從標(biāo)注輸入流cin中讀取字符串對(duì)象(str),然后再?gòu)倪@個(gè)字符串對(duì)象中提取數(shù)值a和b。(4)字符串和其它數(shù)據(jù)類型的轉(zhuǎn)換將字符串內(nèi)容轉(zhuǎn)換成數(shù)字型變量的功能在數(shù)據(jù)處理中經(jīng)常會(huì)用到。例如一個(gè)字符串的內(nèi)容可能是"1234",如何轉(zhuǎn)換為一個(gè)整數(shù)?因此,函數(shù)庫(kù)cstdlib提供了3個(gè)有用的函數(shù):atoi:將字符串string轉(zhuǎn)換為整型int;atol:將字符串string轉(zhuǎn)換為長(zhǎng)整型long;atof:將字符串string轉(zhuǎn)換為浮點(diǎn)型double;所有這些函數(shù)接受一個(gè)參數(shù),返回一個(gè)指定類型的數(shù)據(jù)(int、long或float)。這三個(gè)函數(shù)與cin.getline一起使用來(lái)獲得用戶輸入的數(shù)值,比傳統(tǒng)的cin>>方法更可靠。26下面的例子體現(xiàn)其應(yīng)用:#include<iostream>#include<cstdlib>usingnamespacestd;intmain(){charstr[50];doublea;intb;cout<<"a=?";cin.getline(str,50);a=atof(str);cout<<"b=?";cin.getline(str,50);b=atoi(str);cout<<"a*b="<<a*b;return0;}27此代碼的執(zhí)行過(guò)程中,如果對(duì)第一個(gè)str輸入字符串11,對(duì)第二個(gè)str輸入字符串22,那么轉(zhuǎn)換成整型后分別賦給變量a和b,相乘后輸出結(jié)果為242。1.4動(dòng)態(tài)內(nèi)存分配目前我們所接觸到的程序,所聲明的變量、數(shù)組和其他對(duì)象所必需的內(nèi)存空間都是確定的。但如果我們需要內(nèi)存大小為一個(gè)變量,其數(shù)值只有在程序運(yùn)行時(shí)才能確定,那該如何處理呢?可以采用C++提供的動(dòng)態(tài)內(nèi)存分配方法來(lái)處理,為此C++集成了操作符new和delete。28(1)操作符new和new[]
用操作符new開(kāi)辟動(dòng)態(tài)內(nèi)存空間,關(guān)鍵字new后面跟一個(gè)數(shù)據(jù)類型,并跟一對(duì)可選的方括號(hào)“[]”,里面為要求的元素?cái)?shù)。其結(jié)果返回一個(gè)指向內(nèi)存塊起始位置的指針。其形式為:p=newtype //給一個(gè)單元素的數(shù)據(jù)類型分配內(nèi)存或者p=newtype[elements] //給一個(gè)數(shù)組分配內(nèi)存29例如:int*p;p=newint[10];
上述代碼的操作結(jié)果,操作系統(tǒng)分配了可存儲(chǔ)10個(gè)int元素的內(nèi)存空間,返回指向這塊空間起始位置的指針并將它賦給p。因此,現(xiàn)在p指向一塊可存儲(chǔ)10個(gè)整型元素的合法的內(nèi)存空間。
這種分配數(shù)組空間的做法與定義一個(gè)普通的數(shù)組思路是不同的,定義普通的數(shù)組,數(shù)組的長(zhǎng)度是常量,而采用動(dòng)態(tài)內(nèi)存分配,數(shù)組的長(zhǎng)度可以常量,也可以是變量,其長(zhǎng)度大小在程序執(zhí)行過(guò)程中確定。
動(dòng)態(tài)內(nèi)存分配通常由操作系統(tǒng)控制,由于在多任務(wù)的環(huán)境中,它可以被多個(gè)應(yīng)用所共享,因此,極端情況內(nèi)存有可能被用光。如果這種極端情況情況發(fā)生,操作系統(tǒng)將無(wú)法在遇到操作符new時(shí)再分配所需的內(nèi)存,那么這個(gè)時(shí)候?qū)⒎祷匾粋€(gè)無(wú)效指針(nullpointer)。因此,為了程序的可靠性,建議在使用new之后要檢查返回的指針是否為空(null),如下例所示:int*p;p=newint[10];if(p==NULL){cout<<"errorassigningmemory.Takemeasures.";};31(2)刪除操作符delete
既然動(dòng)態(tài)分配的內(nèi)存只是在程序運(yùn)行的某一具體階段才有用,那么一旦它不再被需要時(shí)就應(yīng)該被釋放,以便回收內(nèi)存,免得發(fā)生極端情況,內(nèi)存被用光。操作符delete的使用形式如下:deleteP; //刪除給單個(gè)元素分配的內(nèi)存或delete[]p;//刪除多元素(數(shù)組)的內(nèi)存分配32下面是一個(gè)應(yīng)用例子:#include<iostream>usingnamespacestd;intmain(){charinput[10];inti,n;long*j;cout<<"希望開(kāi)幾個(gè)元素的數(shù)組?";cin.getline(input,10);i=atoi(input);j=newlong[i];if(j==NULL) exit(1);for(n=0;n<i;n++){cout<<"輸入數(shù)據(jù):";cin.getline(input,10);j[n]=atol(input);}cout<<"輸入內(nèi)容如下:";for(n=0;n<i;n++)cout<<j[n]<<"\n";delete[]j;return0;}此代碼可以記錄用戶希望輸入的任意多個(gè)數(shù)字,它的實(shí)現(xiàn)主要是通過(guò)動(dòng)態(tài)地向系統(tǒng)申請(qǐng)用戶要輸入的數(shù)字所需的空間。1.5“類”是什么?類(class)是一種將數(shù)據(jù)和函數(shù)組織在同一個(gè)結(jié)構(gòu)里的邏輯方法。定義類的關(guān)鍵字為class,其功能與C語(yǔ)言中的struct類似,不同之處是class可以包含函數(shù),而不像struct只能包含數(shù)據(jù)元素。341.5.1類的定義class類名:基類名{
private:
私有成員數(shù)據(jù)及函數(shù);
protected:
保護(hù)成員數(shù)據(jù)及函數(shù);public:
公共成員數(shù)據(jù)及函數(shù);}[類的對(duì)象聲明];35從類的定義可以看到,一個(gè)類含有私有、保護(hù)和公共三部分。缺省時(shí)在類中定義的項(xiàng)都是私有的。private部分的數(shù)據(jù)和函數(shù)只能被該類本身聲明的函數(shù)存?。籶rotected部分的成員除可以被本類中的成員函數(shù)訪問(wèn)外,還可以被本類派生的類的成員函數(shù)訪問(wèn),因此用于類的繼承;public部分的成員可以被本類以外的函數(shù)訪問(wèn),是類與外部的接口。在定義一個(gè)class成員的時(shí)候沒(méi)有聲明其允許范圍,這些成員將被默認(rèn)為private范圍。如:CRectangle的類:classCRectangle{intx,y;public:voidset_values(int,int);intarea(void);}rect;
上述代碼定義的CRectangle類及其對(duì)象變量rect。含:兩個(gè)private的整型變量x和y,兩個(gè)函數(shù)的原型,并沒(méi)有函數(shù)體(函數(shù)體需另行定義)36
在C++中,“對(duì)象”是聲明為“類”類型的一個(gè)數(shù)據(jù)項(xiàng),是類的實(shí)際變量。這個(gè)定義的類的變量就被稱為對(duì)象。對(duì)象有時(shí)也稱為類的實(shí)例(Instance)。37
由此可見(jiàn),類是程序中的一個(gè)靜態(tài)的概念,而對(duì)象是程序中的一個(gè)動(dòng)態(tài)的概念。在C++中有兩種方法可以定義類的對(duì)象:第一種是在定義類的同時(shí)直接定義類的對(duì)象,即在定義類的右大括號(hào)“}”后直接寫(xiě)出屬于該類的對(duì)象名表列。如:class類名{
成員變量表列;
成員函數(shù)表列;}對(duì)象名表列;
第二種是在定義好類后,再定義類的對(duì)象,其一般格式如下:
類名對(duì)象1[,對(duì)象2,…];在C++中通常也把類的成員函數(shù)稱為類的方法;39類的方法成員函數(shù)的原型一般在類的定義中聲明,其語(yǔ)法與聲明普通的函數(shù)所用的語(yǔ)法完全相同;方法的具體實(shí)現(xiàn),可以在類的定義內(nèi)部完成(這種方式定義的類的方法有時(shí)也稱為類的內(nèi)聯(lián)函數(shù)),也可以在類的定義之外進(jìn)行,而且方法的具體實(shí)現(xiàn)既可以和類的定義放在同一個(gè)源文件中,也可以放在不同的源文件中。方法的具體實(shí)現(xiàn)和普通函數(shù)的具體實(shí)現(xiàn)只是在函數(shù)的頭部有略微不同的格式。一般來(lái)說(shuō),如果類的方法的定義是在類的外部實(shí)現(xiàn)的,則在定義方法時(shí)必須把類名放在方法名之前,中間用作用域運(yùn)算符(“::”)隔開(kāi),其一般形式如下所示:
類名::方法名這樣,即使幾個(gè)類中的方法名相同,也可以用這種形式把它們區(qū)分開(kāi)來(lái)。在C++中通常也把類的成員函數(shù)稱為類的方法。成員函數(shù)的原型一般在類的定義中聲明,在類的定義中聲明其成員函數(shù)的語(yǔ)法與聲明普通的函數(shù)所用的語(yǔ)法完全相同。方法的具體實(shí)現(xiàn),可以在類的定義內(nèi)部完成(這種方式定義的類的方法有時(shí)也稱為類的內(nèi)聯(lián)函數(shù)),也可以在類的定義之外進(jìn)行,而且方法的具體實(shí)現(xiàn)既可以和類的定義放在同一個(gè)源文件中,也可以放在不同的源文件中。41一個(gè)簡(jiǎn)單的類的定義classCRectangle{
intx,y;public:voidset_values(int,int);intarea(void);}rect;42這個(gè)例子定義了一個(gè)CRectangle類和該class類型的對(duì)象變量rect。這個(gè)類有4個(gè)成員:兩個(gè)整型變量(x和y),在private部分(沒(méi)寫(xiě)private的就是缺省);兩個(gè)函數(shù),set_values()和area(),在public部分,這里只包含了函數(shù)的原型。
類是面向?qū)ο蟪绦蛟O(shè)計(jì)最基本的單元,在設(shè)計(jì)面向?qū)ο蟪绦驎r(shí),首先要以類的方式描述實(shí)際待解決的問(wèn)題,也就是將問(wèn)題所要處理的數(shù)據(jù)定義成類的私有或公共類型的數(shù)據(jù),同時(shí)將處理問(wèn)題的方法定義成類的私有或公有的成員函數(shù)。對(duì)象成員的引用:
對(duì)象名.成員名用此方式引用對(duì)象rect的任何public成員,例如:rect.set_value(10,20);my_area=rect.area();
但不能直接引用x或y,因?yàn)樗鼈兪窃揷lass的private成員,它們只能夠在該class的其它成員中被引用。4344下面的例子計(jì)算矩形的面積。#include<iostream>usingnamespacestd;classCRectangle{intx,y;public:voidset_values(int,int);intarea(void){return(x*y);}};voidCRectangle::set_values(intm,intn){x=m;y=n;}intmain(){CRectanglerecta,rectb;recta.set_values(10,20);rectb.set_values(30,40);cout<<"rectaarea:"<<recta.area()<<endl;cout<<"rectbarea:"<<rectb.area()<<endl;return0;}將set_values函數(shù)體的定義放在class定義之外,而將area函數(shù)體的定義放在calss定義之內(nèi)。在class內(nèi)部直接定義完整的函數(shù)和把具體實(shí)現(xiàn)放在class外部的區(qū)別在于,直接定義時(shí),編譯器會(huì)自動(dòng)將函數(shù)作為inline(內(nèi)聯(lián)函數(shù),后續(xù)介紹)考慮,而在class外部定義時(shí),函數(shù)只是一般的class成員函數(shù)。45調(diào)用函數(shù)recta.area()與調(diào)用rectb.area()所得到的結(jié)果是不一樣的。這是因?yàn)槊恳粋€(gè)classCRectangle的對(duì)象都擁有它自己的變量x和y,以及它自己的函數(shù)set_value()和area()。在這個(gè)具體的例子中,我們討論的class是CRectangle,有兩個(gè)實(shí)例,或稱對(duì)象recta和rectb,每一個(gè)有它自己的成員變量和成員函數(shù)。
方法的具體實(shí)現(xiàn)和普通函數(shù)的具體實(shí)現(xiàn)只是在函數(shù)的頭部有略微不同的格式。
如果類的方法的定義是在類的外部實(shí)現(xiàn)的,則在定義方法時(shí)必須把類名放在方法名之前,中間用作用域運(yùn)算符(“::”)隔開(kāi),其一般形式如下所示:類名::方法名如:voidCRectangle::set_values(intm,intn)
46即使幾個(gè)類中的方法名相同,也可以用這種形式把它們區(qū)分開(kāi)下面的代碼在程序中定義一個(gè)名為angle的類,然后求sin函數(shù)在60度時(shí)候的值。#include<iostream>#include<cmath>usingnamespacestd;constdoubleANG_TO_RAD=0.0174532925;//定義弧度和度之間的轉(zhuǎn)換比例classangle //定義類angle{doublevalue; //類angle的私有數(shù)據(jù)成員public: //類angle的公共成員函數(shù)voidSetValue(double);doubleGetSine(void);}deg; //聲明類angle的對(duì)象deg4748voidangle::SetValue(doublea)//成員函數(shù)SetValue{ value=a; }
doubleangle::GetSine(void) //成員函數(shù)GetSine{ doubletemp; temp=sin(ANG_TO_RAD*value); returntemp;}
intmain(){deg.SetValue(60.0);//給類angle的成員value賦值
cout<<"Thesineoftheangleis:";cout<<deg.GetSine()<<endl; //輸出正弦值return0;}類也可以嵌套聲明,例如:
classMy_student
{classboy //嵌入類boy,作為類My_student的成員之一{ charboy_name[20]; intboy_age;}my_boy_student;
classgirl //嵌入類girl,作為類My_student的成員之一{ chargirl_name[20]; intgirl_age;}my_girl_student;public: voidstudent_input(void); voidstudent_output(void);};49#include<iostream>usingnamespacestd;classOuter{public:classInner
{public:voidFun();
};public:Innerobj_;voidFun()
{cout<<"Outer::Fun"<<endl;obj_.Fun();
}};50一個(gè)類嵌套的例子51voidOuter::Inner::Fun(){cout<<"Inner::Fun..."<<endl;}voidFun(){classLocalClass
{public:intnum_;voidInit(intnum)
{num_=num;
}voidDisplay()
{cout<<"num_"<<num_<<endl;
}
};LocalClasslc;lc.Init(10);lc.Display();}intmain(){Outerm;m.Fun();Outer::Inneri;i.Fun();Fun();return0;}1.5.2內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)是指那些定義在類體內(nèi)的成員函數(shù),即該函數(shù)的函數(shù)體放在類體內(nèi),類的方法也可以聲明和定義成內(nèi)聯(lián)函數(shù);52內(nèi)聯(lián)函數(shù)在調(diào)用時(shí)不像一般的函數(shù)那樣要轉(zhuǎn)去執(zhí)行被調(diào)用函數(shù)的函數(shù)體,執(zhí)行完成后再轉(zhuǎn)回調(diào)用函數(shù)中,執(zhí)行其后語(yǔ)句,而是在調(diào)用函數(shù)處用內(nèi)聯(lián)函數(shù)體的代碼來(lái)替換,這樣會(huì)提高運(yùn)行速度。因此內(nèi)聯(lián)函數(shù)主要是解決程序的運(yùn)行效率問(wèn)題;值得注意的是,內(nèi)聯(lián)函數(shù)一定要在調(diào)用之前定義,且內(nèi)聯(lián)函數(shù)無(wú)法遞歸調(diào)用。內(nèi)聯(lián)函數(shù)的兩種定義方式當(dāng)在函數(shù)的外部定義時(shí),把關(guān)鍵字inline加在函數(shù)定義之前。例如:下面的程序段中定義的類angle的SetValue方法被定義成內(nèi)聯(lián)函數(shù)。classangle //定義類angle{private:doublevalue;public:voidSetValue(double);};inlinevoidangle::SetValue(doublex)//定義內(nèi)聯(lián)函數(shù){ value=x;}53(2)把函數(shù)原型聲明和方法的定義合并,放入類定義中例如,下面的程序段在聲明類angle的SetValue方法后,緊接著就定義該方法的具體實(shí)現(xiàn)。classangle //定義類angle{private:doublevalue; //定義私有數(shù)據(jù)成員public:
voidSetValue(doublex) //定義內(nèi)聯(lián)函數(shù){ value=x;}};54#include<iostream>usingnamespacestd;classCRectangle{intx,y;public:voidset_values(int,int);intarea(void){return(x*y);}};voidCRectangle::set_values(inta,intb){x=a;y=b;}intmain(){CRectanglerect;rect.set_values(5,6);cout<<"rectarea:"<<rect.area()<<endl;return0;}551.6構(gòu)造函數(shù)和析構(gòu)函數(shù)C++中有幾類特殊的成員函數(shù),這些函數(shù)決定了如何建立、初始化、拷貝及刪除對(duì)象。構(gòu)造函數(shù)和析構(gòu)函數(shù)是其中最重要的兩種。56和一般的成員函數(shù)一樣,構(gòu)造函數(shù)和析構(gòu)函數(shù)既可以在類的內(nèi)部聲明和定義;也可以在類的內(nèi)部聲明,在類的外部定義。如果一個(gè)類含有構(gòu)造函數(shù),則在建立該類的對(duì)象時(shí)就要調(diào)用它;而如果一個(gè)類含有析構(gòu)函數(shù),則在銷毀該類的對(duì)象時(shí)調(diào)用它。1.6.1構(gòu)造函數(shù)對(duì)象(object)在生成過(guò)程中通常需要初始化變量或分配動(dòng)態(tài)內(nèi)存,以便我們能夠操作,或防止在執(zhí)行過(guò)程中返回意外結(jié)果。構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用來(lái)為對(duì)象分配內(nèi)存空間,對(duì)類的數(shù)據(jù)成員進(jìn)行初始化并執(zhí)行對(duì)象的其他內(nèi)部管理操作。構(gòu)造函數(shù)的特點(diǎn):構(gòu)造函數(shù)的名字和它所在的類名相同,當(dāng)定義該類的對(duì)象時(shí),構(gòu)造函數(shù)完成對(duì)此對(duì)象的初始化。它可以接收參數(shù)并允許重載。當(dāng)一個(gè)類含有多個(gè)構(gòu)造函數(shù)時(shí),編譯程序?yàn)榱舜_定調(diào)用哪一個(gè)構(gòu)造函數(shù),需要把對(duì)象中使用的參數(shù)和構(gòu)造函數(shù)的參數(shù)表進(jìn)行比較,此過(guò)程與在普通的函數(shù)重載中進(jìn)行選擇的過(guò)程相同#include<iostream>#definePI3.1415926usingnamespacestd;classCVolume{intr,h;public:CVolume(int,int);doublevolume(void){return(PI*r*r*h);}};
CVolume::CVolume(inta,intb){r=a; h=b;}
intmain(){CVolumevol(5,6);cout<<"Volume="<<vol.volume()<<endl;return0;}58構(gòu)造函數(shù)的名字和它所在的類的名字相同構(gòu)造函數(shù)沒(méi)有返回值,也沒(méi)有void類型聲明。這時(shí)一種規(guī)則。關(guān)于構(gòu)造函數(shù)的幾個(gè)問(wèn)題(1)構(gòu)造函數(shù)和普通函數(shù)一樣也可以有參數(shù),但不能有返回值。這是因?yàn)闃?gòu)造函數(shù)通常是在定義一個(gè)新的對(duì)象時(shí)調(diào)用,它無(wú)法檢查構(gòu)造函數(shù)的返回值。59(2)在實(shí)際應(yīng)用中,如果沒(méi)有給類定義構(gòu)造函數(shù),則編譯系統(tǒng)將為該類生成一個(gè)缺省的構(gòu)造函數(shù),該缺省的構(gòu)造函數(shù)沒(méi)有參數(shù),只是簡(jiǎn)單地把對(duì)象中的每個(gè)實(shí)例變量初始化為0。(3)構(gòu)造函數(shù)可以有缺省參數(shù)。
例如,下面定義的類CVolume中的構(gòu)造函數(shù)#include<iostream>#definePI3.1415926usingnamespacestd;classCVolume{intr,h;public:CVolume(int,int);doublevolume(void){return(PI*r*r*h);}};CVolume::CVolume(inta=5,intb=6){r=a; h=b;}intmain(){CVolumevol;cout<<"Volume="<<vol.volume()<<endl;return0;}構(gòu)造函數(shù)CVolume的兩個(gè)參數(shù)均為缺省參數(shù),在定義對(duì)象時(shí)可以省略或部分省略實(shí)參。因此,可以把main函數(shù)改寫(xiě)成如下形式:intmain(){CVolumevol1(1,2),vol2(1),vol3;cout<<"Volume1="<<vol1.volume()<<endl;cout<<"Volume2="<<vol2.volume()<<endl;cout<<"Volume3="<<vol3.volume()<<endl;return0;}這時(shí)的輸出結(jié)果如下:Volume1=6.28319Volume2=18.8496Volume3=471.23961對(duì)于vol1(1,2),那么原來(lái)缺省值失效;對(duì)于vol2(1),那么按參數(shù)順序,a被重新初始化為1,而參數(shù)b沒(méi)有被初始化,保留原來(lái)的缺省值6;對(duì)于vol3,由于沒(méi)有給出新的參數(shù),完全采用原來(lái)缺省的參數(shù)值。(4)構(gòu)造函數(shù)也可以沒(méi)有參數(shù)。例如,下面定義的類My_class中的構(gòu)造函數(shù)就沒(méi)有參數(shù),該類的構(gòu)造函數(shù)#include<iostream>usingnamespacestd;classCVolume{public:CVolume() { cout<<"NOPARAMETER"<<endl; }};intmain(){CVolume();return0;}1.6.2析構(gòu)函數(shù)析構(gòu)函數(shù)也是類中的特殊成員函數(shù),與定義它的類具有相同的名字,但要在前面加上一個(gè)波浪號(hào)(“~”)。析構(gòu)函數(shù)沒(méi)有參數(shù),也沒(méi)有返回值,而且也不能重載,因此一個(gè)類中只能有一個(gè)析構(gòu)函數(shù)。63析構(gòu)函數(shù)執(zhí)行與構(gòu)造函數(shù)相反的操作,通常用于釋放分配給對(duì)象的存儲(chǔ)空間。當(dāng)程序超出類對(duì)象的作用域時(shí),或者當(dāng)對(duì)一個(gè)類指針使用運(yùn)算符delete時(shí),系統(tǒng)將自動(dòng)調(diào)用析構(gòu)函數(shù)。和構(gòu)造函數(shù)一樣,如果在類的定義中不定義析構(gòu)函數(shù),編譯系統(tǒng)將為之產(chǎn)生一個(gè)缺省的析構(gòu)函數(shù),對(duì)于大多數(shù)類來(lái)說(shuō),缺省的析構(gòu)函數(shù)就能滿足要求。如果在一個(gè)對(duì)象完成其操作之前還需要做一些內(nèi)部處理,則應(yīng)定義析構(gòu)函數(shù)。例如,下面定義的類My_class中定義了該類的析構(gòu)函數(shù)。classMy_class{ char*str; intMaxLen;public: My_class(char*) //定義類My_class的構(gòu)造函數(shù){ str=newchar[MaxLen]; } ~My_class() //構(gòu)造類My_class的析構(gòu)函數(shù){ cout<<"Heredeletethestr"<<endl; deletestr;}voidGetString(char*);};
上面的例子是析構(gòu)函數(shù)和構(gòu)造函數(shù)最常見(jiàn)的用法,即在構(gòu)造函數(shù)中用運(yùn)算符new為字符串分配存儲(chǔ)空間,最后在析構(gòu)函數(shù)中用delete釋放已分配的存儲(chǔ)空間。
析構(gòu)函數(shù)也可以在類定義的內(nèi)部聲明而在類定義的外部定義。例如,上面的析構(gòu)函數(shù)My_class在類定義的外部定義如下:My_class::~My_class(){ deletestr;}析構(gòu)函數(shù)的應(yīng)用:#include<iostream>#definePI3.1415926usingnamespacestd;classCVolume{int*r,*h;public:CVolume(int,int);~CVolume(){cout<<"Heredeletether&h"<<endl;deleter;deleteh;};doublevolume(void){return(PI*(*r)*(*r)*(*h));}};
6667CVolume::CVolume(inta,intb){r=newint;h=newint;*r=a;*h=b;}intmain(){CVolumevola(1,2),volb(3,4);cout<<"vola="<<vola.volume()<<endl;cout<<"volb="<<volb.volume()<<endl;return0;}上述代碼的運(yùn)行結(jié)果如下:vola=6.28319volb=113.097Heredeletether&hHeredeletether&h
上面的例子是析構(gòu)函數(shù)和構(gòu)造函數(shù)最常見(jiàn)的用法,即在構(gòu)造函數(shù)中用運(yùn)算符new為字符串分配存儲(chǔ)空間,最后在析構(gòu)函數(shù)中用delete釋放已分配的存儲(chǔ)空間。析構(gòu)函數(shù)也可以在類定義的內(nèi)部聲明而在類定義的外部定義。例如,上面的析構(gòu)函數(shù)CVolume在類定義的外部定義如下。CVolume::~CVolume(){cout<<"Heredeletethew&h"<<endl;deleter;deleteh;}681.7函數(shù)重載69
重載是C++的一個(gè)重要特征,重點(diǎn)介紹函數(shù)重載所謂函數(shù)重載是指同一個(gè)函數(shù)名可以對(duì)應(yīng)著多個(gè)函數(shù)的實(shí)現(xiàn)。函數(shù)重載允許一個(gè)程序內(nèi)聲明多個(gè)名稱相同的函數(shù),這些函數(shù)可以完成不同的功能,并可以帶有不同的類型、不同數(shù)目的參數(shù)及返回值。使用函數(shù)重載可以減輕用戶的記憶負(fù)擔(dān),并使程序的結(jié)構(gòu)簡(jiǎn)單、易懂。下例實(shí)現(xiàn)的是兩個(gè)不同參數(shù)類型的重載。在類My_class中對(duì)方法plus進(jìn)行了重載,通過(guò)重載,使得在求兩個(gè)數(shù)的和時(shí)不用再區(qū)分整數(shù)和浮點(diǎn)數(shù)之間的不同之處,而只需直接調(diào)用類My_class的方法plus即可。#include<iostream>usingnamespacestd;classMy_class{public:intplus(int,int);doubleplus(double,double);};intMy_class::plus(intx,inty){returnx+y;}doubleMy_class::plus(doublex,doubley){returnx-y;}intmain(){My_classData;cout<<"Theresultforplus(int,int)is:"<<Data.plus(5,10)<<endl;cout<<"Theresultforplus(double,double)is:"<<Data.plus(5.0,10.0)<<endl;return0;}兩個(gè)重載的成員函數(shù)分別調(diào)用求整型數(shù)之加和和求浮點(diǎn)數(shù)之加和的函數(shù)plus來(lái)對(duì)不同的參數(shù)進(jìn)行求和運(yùn)算。
函數(shù)重載要求編譯器能夠唯一地確定調(diào)用一個(gè)函數(shù)時(shí)應(yīng)執(zhí)行哪個(gè)函數(shù)代碼。確定函數(shù)實(shí)現(xiàn)時(shí),要求從函數(shù)參數(shù)的個(gè)數(shù)和類型上來(lái)區(qū)分。也就是說(shuō),函數(shù)重載時(shí),要求函數(shù)的參數(shù)個(gè)數(shù)或參數(shù)類型不同。
不僅在類的成員函數(shù)上可以實(shí)現(xiàn)重載,在構(gòu)造函數(shù)上,也可以實(shí)現(xiàn)函數(shù)的重載。例如:#include<iostream>usingnamespacestd;classCSample{inti;public:CSample(); //定義重載的構(gòu)造函數(shù)CSample(int);intarea(void){return(i);}};
在處理不同類型的數(shù)據(jù)時(shí),成員函數(shù)的重載使得類具有更大的靈活性和通用性,這也有力地支持了通過(guò)類來(lái)對(duì)我們周圍的客觀世界進(jìn)行抽象的程序設(shè)計(jì)的思想。CSample::CSample() //定義構(gòu)造函數(shù)sample{i=0;cout<<"sampleA,i="<<i<<endl;}CSample::CSample(intx) //定義構(gòu)造函數(shù)sample(int){i=x;cout<<"sampleB(5),i="<<i<<endl;}intmain(){CSamplej1,j2(5);cout<<"j1.area()="<<j1.area()<<endl;//調(diào)用構(gòu)造函數(shù)Csamplecout<<"j2.area()="<<j2.area()<<endl;//調(diào)用構(gòu)造函數(shù)Csample(int)return0;}定義重載的構(gòu)造函數(shù)后,聲明對(duì)象時(shí)就可以根據(jù)不同的參數(shù)來(lái)分別調(diào)用不同的構(gòu)造函數(shù)。應(yīng)用重載的構(gòu)造函數(shù)求圓柱體的體積:#include<iostream>#definePI3.1415926usingnamespacestd;classCVolume{intr,h;public:CVolume();CVolume(int,int);doublevolume(void){return(PI*r*r*h);}};
CVolume::CVolume(){r=10;h=20;}7374CVolume::CVolume(intm,intn){r=m;h=n;}
intmain(){CVolumeVole1(3,4);CVolumeVole2;cout<<"Vole1="<<Vole1.volume()<<endl;cout<<"Vole2="<<Vole2.volume()<<endl;return0;}在上面的例子中,Vole2被聲明的時(shí)候沒(méi)有參數(shù),所以它被使用沒(méi)有參數(shù)的構(gòu)造函數(shù)進(jìn)行初始化,也就是r和h分別被賦值為10和20。值得注意的是,如果在我們聲明一個(gè)新的對(duì)象的時(shí)候不需要傳入?yún)?shù),則不要寫(xiě)括號(hào)“()”,如“CVolumeVole2;”這個(gè)語(yǔ)句就沒(méi)有使用括號(hào)。1.8友元
類的主要特點(diǎn)是數(shù)據(jù)隱藏,即類的私有部分在該類的作用域之外是不可見(jiàn)的。
但有時(shí)候可能需要在類的外部訪問(wèn)類的私有部分。為此,C++提供了一種方法,允許類外部的函數(shù)或者類具有該類的私有部分的特權(quán),它通過(guò)關(guān)鍵字friend把其它類或非成員函數(shù)聲明為一個(gè)類的“友元”。
在類的內(nèi)部,友元被作為該類的成員看待,并且對(duì)對(duì)象公用部分的訪問(wèn)沒(méi)有任何限制。75友元函數(shù)的聲明方式為:class類名稱{typevars;…public:friend函數(shù)類型函數(shù)名稱();//友元函數(shù)…}例如,下面定義了類friend_Class及友元函數(shù)friend_Function。class friend_Class //類friend_Class的定義{private: intnMemberData;public: //聲明函數(shù)Friend_Function為類Friend_Class的友元
friendvoidfriend_function(friend_Classclass_member,intx);};
77//下面是友元函數(shù)friend_function的函數(shù)體,它要在類的外部定義voidfriend_function(friend_Classclass_member,intx){class_member.nMemberData=x;//通過(guò)友元函數(shù)訪問(wèn)類的私有成員}上面代碼中函數(shù)friend_function并不是類friend_Class的成員函數(shù),而是一個(gè)普通的函數(shù),不過(guò)由于它在類friend_Class的定義中被聲明為友元函數(shù),因此,函數(shù)friend_function可以訪問(wèn)類friend_Class的私有部分友元函數(shù)的應(yīng)用:#include<iostream>usingnamespacestd;classCRectangle{intwidth,height;public:voidset_values(int,int);intarea(void){return(width*height);}
friendCRectangleduplicate(CRectangle);};voidCRectangle::set_values(inta,intb){width=a;height=b;}CRectangleduplicate(CRectanglerectparam){CRectanglerectres;rectres.width=rectparam.width*2;rectres.height=rectparam.height*2;return(rectres);}intmain(){CRectanglerect,rectb;rect.set_values(2,3);rectb=duplicate(rect);cout<<rectb.area();return0;}8.2.8友元類就像我們可以定義一個(gè)friend函數(shù),我們也可以定義一個(gè)class是另一個(gè)的friend,以便允許第二個(gè)class訪問(wèn)第一個(gè)class的protected和private成員。80//#include"stdafx.h"#include<iostream>usingnamespacestd;classCSquare;classCRectangle{intwidth,height;public:intarea(void){return(width*height);}voidconvert(CSquarea);};classCSquare{private:intside;public:voidset_side(inta){side=a;}friendclassCRectangle;};81這里聲明了CRectangle是CSquare的friend,因此CRectangle可以訪問(wèn)CSquare的protected和private成員,更具體地說(shuō),可以訪問(wèn)CSquare::side,它定義了正方形的邊長(zhǎng)。voidCRectangle::convert(CSquarea){width=a.side;height=a.side;}intmain(){CSquaresqr;CRectanglerect;sqr.set_side(4);rect.convert(sqr);cout<<rect.area();return0;}類的友元可以是一個(gè)函數(shù),也可以是一個(gè)類。例如,下面的程序中將整個(gè)教師類看成是學(xué)生類的友元:classStudent;classTeacher{public:voidassignGrades(Student&s);voidadjustHours(Student&s);protected:intNoOfStudent;Student*pList[100];};classStudent{public:
friendclassTeacher;//友類protected:intsemesterHours;floatgpa;};
Teacher是友元類,它必須在它被定義以前聲明,因此,類Teacher的定義在類Student之前。一旦一個(gè)類被聲明為另一個(gè)類的友元之后,該類的每一個(gè)成員函數(shù)都是另一個(gè)類的友元函數(shù)。一個(gè)類的友元的聲明既可以在該類定義的公用部分聲明,也可以在類的私有部分聲明。兩個(gè)類還可以相互定義為對(duì)方的友元,當(dāng)兩個(gè)類的聯(lián)系較緊密時(shí),把它們定義為相互的友元就更為有意義了。1.9類的指針
指針大家都很熟悉,在C++中,和其他數(shù)據(jù)類型一樣,程序中也可以定義指向類對(duì)象的指針,類一旦被定義就成為一種有效的數(shù)據(jù)類型,只需要用類的名字作為指針的類型就可以了。在定義了類的指針后,還必須為其分配內(nèi)存才能使用,類對(duì)象的指針定義及分配內(nèi)存空間的一般格式為:類名*指針名=new類名;例如:CMy_class*p=newCMy_class;
這里定義的指針p就是一個(gè)指向classCMy_class類型的對(duì)象的指針。如果要想直接引用一個(gè)由指針指向的對(duì)象中的成員,同樣可以使用操作符“->”。84這里是一個(gè)例子,顯示了幾種可能出現(xiàn)的情況:#include<iostream>#definePI3.1415926usingnamespacestd;classCVolume{intr,h;public:voidparam(int,int);doublevolume(void){return(PI*r*r*h);}};
voidCVolume::param(intm,intn){r=m;h=n;}
85intmain(){CVolumea,*b,*c;CVolume*d=newCVolume[2];b=newCVolume;c=&a;a.param(1,2);b->param(3,4);d->param(5,6);d[1].param(7,8);cout<<"avolume:"<<a.volume()<<endl;cout<<"*bvolume:"<<b->volume()<<endl;cout<<"*cvolume:"<<c->volume()<<endl;cout<<"d[0]volume:"<<d[0].volume()<<endl;cout<<"d[1]volume:"<<d[1].volume()<<endl;return0;}
上述代碼中定義了CVolume類的指針b、c和d,然后d的指針指向了CVolume對(duì)象的首地址,b指針指向了CVolume類的對(duì)象,然后分別調(diào)用CVolume類的成員函數(shù)volume求體積。avolume:6.28319*bvolume:113.097*cvolume:6.28319d[0]volume:471.239d[1]volume:1231.5大家再來(lái)看看下面的例子,這里定義了類class1以及指向class1對(duì)象的指針p。#include<iostream>usingnamespacestd;classClass1 //定義類Class1{intValue; //定義類的私有成員public:Class1(intVal) //類Class1的構(gòu)造函數(shù){ Value=Val; //對(duì)成員變量初始化}intGetValue(void) //類Class1的成員函數(shù){returnValue; //獲取類對(duì)象的成員變量的值}};intmain() //主函數(shù){Class1Object1(888),*p; //定義類Class1的對(duì)象和一個(gè)對(duì)象指針p=&Object1; //使對(duì)象指針指向?qū)ο驩bject1cout<<"ThevalueofObject1is:"<<p->GetValue()<<endl; //用對(duì)象指針調(diào)用成員函數(shù)return0;}87代碼中,由于“p=&Object1;”的執(zhí)行,使得指針p指向了Object1(),然后就把888的值傳給了構(gòu)造函數(shù)class1(),對(duì)構(gòu)造函數(shù)中的Value進(jìn)行了初始化,其值就是888;然后通過(guò)“p->GetValue()”的調(diào)用,返回了Value的值,this指針this指針是指向一個(gè)類的對(duì)象的地址。this是一種隱含指針,它隱含于每個(gè)類的成員函數(shù)之中,也就是說(shuō),每個(gè)成員函數(shù)都有一個(gè)this指針變量,this指針指向該成員函數(shù)所屬的類的對(duì)象。當(dāng)定義一個(gè)類的對(duì)象時(shí),該對(duì)象的成員均含有由系統(tǒng)自動(dòng)產(chǎn)生的指向當(dāng)前對(duì)象的this指針。成員函數(shù)訪問(wèn)類中成員變量的格式可以寫(xiě)成: this->成員變量88當(dāng)一個(gè)對(duì)象調(diào)用成員函數(shù)時(shí),該成員函數(shù)的this指針便指向這個(gè)對(duì)象。若不同的對(duì)象調(diào)用同一個(gè)成員函數(shù),C++編譯器將根據(jù)成員函數(shù)的this指針?biāo)赶虻牟煌瑢?duì)象類確定應(yīng)引用哪一個(gè)對(duì)象的數(shù)據(jù)成員。也就是說(shuō),每個(gè)對(duì)象都有一個(gè)地址,而this指針?biāo)傅木褪沁@個(gè)地址。89和其他數(shù)據(jù)類型一樣,程序中也可以定義指向類對(duì)象的指針,在定義了類的指針后,還必須為其分配內(nèi)存才能使用,類對(duì)象的指針定義及分配內(nèi)存空間的一般格式為:
類名*指針名=new類名;例如,下面的語(yǔ)句定義類Student的對(duì)象指針并為其分配內(nèi)存。
Student*Student1=newStudent;
當(dāng)通過(guò)類對(duì)象的指針訪問(wèn)類的成員時(shí),通??梢允褂眠\(yùn)算符“->”,例如,下面的程序中,主函數(shù)通過(guò)指向類對(duì)象的指針調(diào)用類的成員函數(shù)。#include<iostream>usingnamespacestd;classCMy_class{public:inttest(CMy_class¶m);};90intCMy_class::test(CMy_class¶m){if(¶m==this) return1;else return0;}
intmain(){CMy_classa;CMy_class*b=&a;if(b->test(a))
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 重點(diǎn)企業(yè)領(lǐng)導(dǎo)力培訓(xùn)課件
- 分析天平介紹
- 質(zhì)量體系知識(shí)培訓(xùn)課件
- 致青春我的未來(lái)不是夢(mèng)
- 2026年京東商家自營(yíng)售前售后客服認(rèn)證考試初級(jí)中級(jí)答案解析
- 營(yíng)運(yùn)車輛道路安全培訓(xùn)課件及試題
- 醫(yī)學(xué)導(dǎo)論:創(chuàng)傷后應(yīng)激障礙診療課件
- 醫(yī)學(xué)導(dǎo)論:分子生物學(xué)入門課件
- 護(hù)理質(zhì)量與醫(yī)療設(shè)備管理
- 2025-2030中國(guó)冷卻液市場(chǎng)供需現(xiàn)狀與未來(lái)發(fā)展態(tài)勢(shì)展望研究報(bào)告
- 創(chuàng)傷性脾破裂的護(hù)理
- 蓬深102井鉆井工程(重新報(bào)批)項(xiàng)目環(huán)境影響報(bào)告表
- 馬路切割承包協(xié)議書(shū)
- 大模型金融領(lǐng)域可信應(yīng)用參考框架
- (新教材)2025年人教版七年級(jí)上冊(cè)歷史期末復(fù)習(xí)常考知識(shí)點(diǎn)梳理復(fù)習(xí)提綱(教師版)
- 學(xué)??剌z保學(xué)工作流程及四書(shū)一表一單
- 塔吊拆除應(yīng)急預(yù)案
- 中國(guó)全色盲診療專家共識(shí)2026
- 20052-2024電力變壓器能效限定值及能效等級(jí)
- 2025年環(huán)境衛(wèi)生學(xué)與消毒滅菌效果監(jiān)測(cè)試卷(附答案)
- 冷渣機(jī)調(diào)整課件
評(píng)論
0/150
提交評(píng)論