C++面向?qū)ο蟪绦蛟O(shè)計課件_第1頁
C++面向?qū)ο蟪绦蛟O(shè)計課件_第2頁
C++面向?qū)ο蟪绦蛟O(shè)計課件_第3頁
C++面向?qū)ο蟪绦蛟O(shè)計課件_第4頁
C++面向?qū)ο蟪绦蛟O(shè)計課件_第5頁
已閱讀5頁,還剩599頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

C++面向?qū)ο蟪淌皆O(shè)計

第一章第1章 C++概述C++ABetterC1.1C++起源和特點 1.1.1 C++的起源

1.1.2 C++的特點1.2C++程式的結(jié)構(gòu)1.2.1

C程式與C++程式比較1.2.2

C++程式結(jié)構(gòu)1.2.3

C++程式的編輯、編譯和運行C程式與C++程式比較之一main(){inta,b,sum;/*定義三個整型變數(shù)*/a=123;b=456;

sum=a+b;

printf("sumis%d\n",sum);

}main(){inta,b,sum;

//定義三個整型變數(shù)

a=123;b=456;

sum=a+b;

cout<<sum;

}C程式與C++程式比較之二#include"stdio.h"main(){chara,b,c;a='B';b='O';c='Y';putchar(a);putchar(b);putchar(c);}#include“iostream.h"voidmain(){chara,b,c;a='B';b='O';c='Y';cout<<a<<b<<c;}1.3C++的一些新特性1.3.1單行注釋和新的I/O流1.3.2const修飾符1.3.3內(nèi)聯(lián)函數(shù)1.3.4函數(shù)原型1.3.5帶缺省參數(shù)的函數(shù)1.3.6函數(shù)名重載1.3.7

new和delete運算符1.3.8引用(reference)1.3.1單行注釋和新的I/O流//I/Ostream#include<iostream.h>

main(){inti;floatf;chars[80];

cout<<"Enteraninteger,float,andstring:";cin>>i>>f>>s;cout<<"Here'syourdata:"<<i<<''<<f<<endl<<s<<'\n';return0;}單行注釋和新的I/O流(續(xù))cout是預定義的輸出流對象,類似於C語言中的stdout。<<輸出運算符,可用於輸出C++語言中任何基本類型的數(shù)據(jù)。cin是預定義的輸入流對象,類似於C語言中的stdin。<<輸入運算符,可用於輸入C++語言中任何基本類型的數(shù)據(jù)。(注意:輸入和輸出並不是C++語言的組成部分,它們由流庫iostream支持。)輸入含有空格的字串//Usegetline()toreadastringthatcontainsspaces.#include<iostream>#include<fstream>usingnamespacestd;intmain(){charstr[80];cout<<"Enteryourname:";cin.getline(str,79);cout<<str<<'\n';return0;}1.3.2const存取修飾符

對象A:親愛的,你千萬不能變心?對象B:放心吧!親愛的。對象A:你發(fā)誓!對象B:不用發(fā)誓,因為我是const!

const對象B;常量Constants在C中,可以使用#define來定義符號常量。C++提供了一種更靈活、更安全的方式來定義常量,即使用關(guān)鍵字const來定義符號常量。常量例子ConstantexamplesconstfloatPI=3.1415926;//PI是一個常量constintv[]={1,2,3,4};//數(shù)組元素v[i]是常量constintx;//error:noinitializer//定義常量時應初始化,否則出錯。voidf(){ model=200;//error v[2]++;//error}值替換valuesubstitution#defineBUFSIZE100constintbufsize=100;Becauseofsubtlebugsthatthepreprocessormightintroduce,youshouldalwaysuseconstinsteadof#definevaluesubstitution.常量const和指針指針所指向的對象為常量Pointertoconst指針本身為常量constpointerTheconstmodifiesthethingitis“closestto.”指向常量的指針

Pointertoconstconstint*u;//pointertoconstant*u=18;//error:upointstoconstantu=p;//OK常指針constpointerintd=1;int*constw=&d;*w=2;//OKw=p;//error:wisconstconst修飾函數(shù)參數(shù)voidprint_salary(constfloat*salary){ cout<<salary<<’\n’;}const可以阻止參數(shù)被函數(shù)修改const的其他用途

Otherusesofconstreturntypes,classobjectsandmemberfunctionsvolatile存取修飾符修飾符volatile通知編譯器,變數(shù)值可能由程式中沒有顯示說明的方式所改變,因此在作編譯優(yōu)化時,不要通過將該變數(shù)放入寄存器來提高速度。

Volatile原意是:可變的,不穩(wěn)定的externvolatileclock;externconstvolatileclock;1.3.3內(nèi)聯(lián)函數(shù)(內(nèi)嵌函數(shù),

內(nèi)置函數(shù)inlinefunction)在函數(shù)聲明或定義的前面加上關(guān)鍵字“inline”,該函數(shù)就被聲明為內(nèi)聯(lián)函數(shù)。inlineintmax(intx,inty)//max被說明為內(nèi)聯(lián)函數(shù){intz;if(x>y)z=x;elsez=y;return(z);}內(nèi)聯(lián)函數(shù)的調(diào)用方法與普通函數(shù)沒有區(qū)別。類中定義的內(nèi)聯(lián)函數(shù)InlinefunctionAnyfunctiondefinedwithinaclassbodyisautomaticallyinline,classDate{ intday,month,year;public: voidinit_date(intdd,intmm,intyy) {day=dd;month=mm;year=yy;}};Hereinit_dateisainlinefunction函數(shù)調(diào)用時的時間開銷1.函數(shù)調(diào)用時的時間開銷:保護現(xiàn)場,恢復現(xiàn)場。2.用關(guān)鍵字inline說明內(nèi)嵌函數(shù)。編譯器直接用內(nèi)嵌函數(shù)體的編譯代碼插入在函數(shù)調(diào)用語句處,這一過程稱為函數(shù)的嵌入擴展。利用內(nèi)嵌函數(shù)減少了調(diào)用普通函數(shù)時的壓棧和彈棧操作,從而提高程式的運行速度。3.內(nèi)嵌函數(shù)比帶參數(shù)的宏的好處。一般情況下,只有較短的函數(shù)才定義為內(nèi)嵌函數(shù)。使用內(nèi)嵌函數(shù)實際上是一種增加空間開銷以減小時間開銷的方法。為什麼使用內(nèi)聯(lián)函數(shù)Efficiency

效率

在C程式中,可使用宏macros達到同樣的目的,但是宏是通過預處理來處理的,不進行類型檢查,容易造成難以發(fā)現(xiàn)的錯誤。宏macros在類的內(nèi)部不能使用,宏不能作為類的成員。為什麼使用內(nèi)聯(lián)函數(shù)(cont.)為了克服宏的上述缺陷,C++引入了內(nèi)聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)具有高效率,而且:進行類型檢查,避免出現(xiàn)類型不匹配的錯誤??梢宰鳛轭惖某蓡T函數(shù)。Toretaintheefficiencyofthepreprocessormacro,buttoaddthesafetyandclassscopingoftruefunctions,C++hastheinlinefunction.Howdoinlinefunctionswork

編譯器處理內(nèi)聯(lián)函數(shù)的過程類型檢查Typechecking(Toassuresafety)將函數(shù)代碼插入到函數(shù)調(diào)用處thensubstitutesthefunctionbodyforthefunctioncall這樣函數(shù)代碼將佔據(jù)更所得存儲空間

TheinlinecodedoesoccupyspaceTheshort,smallandfrequentlycalledfunctionsaresuitableforinlinefunctions.1.3.4函數(shù)原型(functionprototype)

什麼是函數(shù)原型?描述函數(shù)原型的三大要素:函數(shù)名參數(shù)類型函數(shù)返回值類型函數(shù)原型的例子:inttranslate(floatx,floaty,floatz);inttranslate(float,float,float);【例1.7】

voidsqr_it();/*functiondeclaration*/intmain(){ intx; x=10; sqr_it(x); printf("Thesquareofxis%d\n",x);return0;}voidsqr_it(int*i){ *i=(*i)*(*i);}運行時出錯【例1.7】本例的C程式能夠成功通過諸如TurboC這樣的C編譯器的檢查,但會在運行階段發(fā)生錯誤。該程式運行後的結(jié)構(gòu)顯示如下:Thesquareofxis10Nullpointerassignment使用函數(shù)原型執(zhí)行強類型檢查【例1.8】voidsqr_it(int*i);//函數(shù)原型

intmain(){ intx; x=10;

sqr_it(x);

cout<<"Thesquareofxis"<<x<<'\n';return0;}voidsqr_it(int*i){ *i=(*i)*(*i);}typemismatch類型不匹配函數(shù)原型的作用C++語言是強類型化語言,任何函數(shù)在使用以前必須有該函數(shù)的原型說明,以便進行實際參數(shù)與形式參數(shù)之間的類型匹配檢查。函數(shù)返回值的類型和函數(shù)參數(shù)的類型、個數(shù)、次序在函數(shù)聲明,函數(shù)定義和函數(shù)調(diào)用時必須匹配。C++語言的編譯器執(zhí)行上述檢查能顯著減少很多隱藏的錯誤。函數(shù)原型與C語言的函數(shù)類型說明函數(shù)原型是在C語言的函數(shù)類型說明(函數(shù)聲明)的基礎(chǔ)上進行擴充後形成的,它不但說明了函數(shù)返回值的類型,還要確定函數(shù)參數(shù)的類型、個數(shù)、次序及缺省值。1.3.5帶缺省參數(shù)的函數(shù)例如:以下函數(shù)帶有一個缺省值為0的參數(shù)。voidmyfunc(doubled=0.0){…}myfunc(198.234);//passanexplicitvaluemyfunc();//letfunctionusedefault缺省參數(shù)的例子voidDrawCircle(intx,inty,intr=10);DrawCircle(50,20);DrawCircle(50,100,30);帶缺省參數(shù)函數(shù)主要由兩個作用:簡化編程;有利於程式擴充,而不影響原有代碼。1.3.6函數(shù)名重載(overload)兩或兩個以上的函數(shù)共用同一個名稱,就稱為函數(shù)名重載。

OverloadedFunctionsMultiplefunctionscanhavethesamenamewithdifferentimplementations.函數(shù)重載簡化了函數(shù)調(diào)用工作。函數(shù)重載的例子#include<iostream.h>

//Overloadabs()threeways

intabs(intn);longabs(longn);doubleabs(doublen);//prototypeisneccessaryforC++compiler這些都是函數(shù)原型函數(shù)重載的例子main(){cout<<"Absolutevalueof-10:"<<abs(-10)<<"\n";cout<<"Absolutevalueof-10L:"<<abs(-10L)<<"\n";cout<<"Absolutevallueof-10.01:"<<abs(-10.01)<<"\n";

return0;}abs()forints//abs()forintsintabs(intn){cout<<"Inintergerabs()\n";returnn<0?-n:n;}abs()forlongs

//abs()forlongslongabs(longn){cout<<"Inlongabs()\n";returnn<0?-n:n;}abs()fordoubles//abs()fordoublesdoubleabs(doublen){cout<<"Indoubleabs()\n";returnn<0?-n:n;}1.3.7

new和delete運算符在C語言中,使用函數(shù)malloc()分配動態(tài)記憶體,用函數(shù)free()釋放動態(tài)記憶體;在C++語言中,還可以使用運算符new分配動態(tài)記憶體,用delete釋放動態(tài)記憶體。

new和delete的簡單應用//Asimpleexampleofnewanddelete.#include<iostream.h>

main(){int*p;

p=newint;//allocateroomforaninteger

//alwaysmakesurethatallocatesucceededif(!p){cout<<"Allocationerror\n";return1;}Asimpleexampleofnewanddelete(cont)*p=1000;

cout<<"Hereisintegeratp:"<<*p<<"\n";

deletep;//releasememory

return0;}new和delete的優(yōu)點new和delete完成的功能類似於malloc()與free(),但它們有幾個優(yōu)點:1)簡潔性:能自動計算所要分配的記憶體的大??;2)可靠性:編譯時進行類型檢查;3)靈活性:new和delete運算符可以被重載。注意:用new申請的動態(tài)記憶體必須用delete釋放。1.3.8引用(reference)引用是一個隱含指針,可以看作變數(shù)的另一個名稱(別名)。引用有三種使用方法:引用作為函數(shù)參數(shù)(最重要的用法)#include<iostream.h>

voidf(int&n);//declareareferenceparameterusing&

main(){inti=0;

f(i);//Theaddressofvariableiispassed.cout<<"Hereisi'snewvalue:"<<i<<'\n';return0;}引用作為函數(shù)參數(shù)(繼續(xù))//f()nowusesareferenceparametervoidf(int&n){//noticethatno*isneededinthefollowingstatementn=100;//put100intotheargumentusedtocallf()}指針參數(shù)和引用參數(shù)的比較//交換實際參數(shù)的值voidswap(int*x,int*y){inttemp;

temp=*x;//保存地址x中的值

*x=*y;//putyintox

*y=temp;//putxintoy}

//調(diào)用函數(shù)swap()時使用變數(shù)i和j的地址

swap(&j,&i);//交換實際參數(shù)的值voidswap(int&x,int&y){inttemp;

temp=x;//保存地址x中的值

x=y;//putyintox

y=temp;//putxintoy}

//調(diào)用函數(shù)swap()時使用變數(shù)i和j的名字

swap(j,i);引用參數(shù)的幾個好處當使用引用參數(shù)的時候,傳遞的是用作參數(shù)的變數(shù)的地址。1)地址被自動傳遞;不需要記住傳遞參數(shù)的地址。2)比指針方法更簡練,清晰。3)當對象作為引用被傳遞給函數(shù)的時候,沒有進行拷貝(複製)。引用作為函數(shù)的返回值

//Asimpleexampleofafunctionreturnnigareference.#include<iostream.h>int&f();intx;

main(){ f()=100;//f()returntheaddressofx

cout<<x<<"\n";

return0;}引用作為函數(shù)的返回值(繼續(xù))

//Returnanintreference.int&f(){returnx;//returnsareferencetox}獨立的引用至今沒有發(fā)現(xiàn)獨立引用的價值,在一個程式中用兩個名字來描述同一個對象,可能使程式出現(xiàn)混亂。(應當避免)對象和類屬於同一個類的所有對象具有某些共性和相似的特徵。一個類定義了一組大體上相似的對象。在面向?qū)ο蟮能涹w系統(tǒng)中,對象是基本的運行時實體,它既包含數(shù)據(jù),也包括作用於這些數(shù)據(jù)的操作。對象對象的組成操作代碼數(shù)據(jù)面向?qū)ο蟮能涹w系統(tǒng)對象4對象1對象3對象2§2.1類和對象的定義2.1.1

C++中對結(jié)構(gòu)的擴展2.1.2

C++中類的定義2.1.3

C++類中的成員函數(shù)定義2.1.4

C++中對象的定義和使用2.1.5

C++中類的介面與實現(xiàn)2.1.6類聲明與類定義2.1.7結(jié)構(gòu)struct與類class的比較2.1.1

C++中對結(jié)構(gòu)的擴展C++中的結(jié)構(gòu)不僅可以包含不同類型的數(shù)據(jù),而且還可以包含函數(shù)。結(jié)構(gòu)中的數(shù)據(jù)和函數(shù)都是結(jié)構(gòu)的成員,分別稱為數(shù)據(jù)成員和函數(shù)成員。在C++中,通常把函數(shù)成員稱為成員函數(shù)。C的結(jié)構(gòu)體struct與C++的struct的比較C語言的結(jié)構(gòu)體中數(shù)據(jù)與操作是分離的

在C++語言中將數(shù)據(jù)與操作封裝在一個結(jié)構(gòu)體中

structStudent{ intnumber; charname[15]; floatscore;};數(shù)據(jù)成員structStudent{intnumber;charname[15];floatscore;voiddisplay()//函數(shù)成員{ cout<<”number:”<<number; cout<<”name:”<<name; cout<<”score:”<<score<<endl;}};/*獨立函數(shù)display*/voiddisplay(Student*stu){ printf(”number:%d”,stu->number); printf(”name:%s”,stu->name); printf(”score:%f\n”,stu->score);}成員函數(shù)數(shù)據(jù)成員2.1.2

C++中類的定義在C++語言中,我們通過定義新的數(shù)據(jù)類型來實現(xiàn)類。類既包含數(shù)據(jù)內(nèi)容又包含對數(shù)據(jù)的操作,所以類是一個抽象數(shù)據(jù)類型。在C++語言中,類可被視為一種用戶定義的類型。C++的結(jié)構(gòu)體struct與C++的class的比較將數(shù)據(jù)與操作封裝在一個C++的結(jié)構(gòu)體struct中將數(shù)據(jù)與操作封裝在一個C++類class中數(shù)據(jù)成員structStudent{intnumber;charname[15];floatscore;voiddisplay()//函數(shù)成員{ cout<<”number:”<<number; cout<<”name:”<<name; cout<<”score:”<<score<<endl;}};數(shù)據(jù)成員classStudent{intnumber;charname[15];floatscore;voiddisplay()//函數(shù)成員{ cout<<”number:”<<number; cout<<”name:”<<name; cout<<”score:”<<score<<endl;}};成員函數(shù)數(shù)據(jù)成員一個複數(shù)結(jié)構(gòu)的例子structcomplex{doublereal;doubleimage;voidinit(doubler,doublei){real=r;image=i;}doublerealcomplex(){returnreal;}…;};成員函數(shù)數(shù)據(jù)成員私有成員和公有成員在C++中一個結(jié)構(gòu)的成員通常分為兩類:私有成員(private)和公有成員(

public)私有成員只能被該結(jié)構(gòu)中的其他成員訪問。公有成員既可以被結(jié)構(gòu)內(nèi)的其他成員訪問,也可以被結(jié)構(gòu)外的成員所訪問。C++規(guī)定,在缺省情況下,結(jié)構(gòu)中的成員是公有的。此處所指成員包括數(shù)據(jù)成員和成員函數(shù)。私有成員和公有成員的聲明structcomplex{private:doublereal;doubleimage;public:voidinit(doubler,doublei){real=r;image=i;}doublerealcomplex(

){returnreal;}…;};私有成員公有成員類的定義class

類名{[private:]

私有數(shù)據(jù)成員和成員函數(shù)public:

公有數(shù)據(jù)成員和成員函數(shù)};//分號是不能少的//其中,class是聲明類的關(guān)鍵字//類名是要聲明的類的名字類中私有成員和公有成員的聲明classcomplex{private:doublereal;doubleimage;public:voidinit(doubler,doublei){real=r;image=i;}doublerealcomplex(){returnreal;}…;};私有成員公有成員定義類時的注意事項private和public可以按任意順序出現(xiàn)具有良好習慣的程式員會:把所有私有成員和公有成員歸類放在一起將私有成員放在公有成員的前面private、public和protected稱為訪問控制符。數(shù)據(jù)成員可以是任何數(shù)據(jù)類型,但不能用auto、register或extern進行說明。只有在類對象定義之後才能給數(shù)據(jù)成員賦初值。為什麼要用類代替結(jié)構(gòu)?在缺省情況下,類中的成員是私有的private。類提供了缺省的安全性。2.1.3

C++類中的成員函數(shù)定義C++類中的成員函數(shù)描述了對類對象內(nèi)部數(shù)據(jù)的操作方法,或者說,描述了對象的行為,因此我們又將成員函數(shù)稱為方法(method)或者服務(service)?!纠?.2】學生類中成員函數(shù)的定義。成員函數(shù)的定義包含在類體中classStudent{private: intnumber; charname[15]; floatscore;public: voidinit(intnumber1,char*name1,floatscore1);

voidmodify(floatscore1) { score=score1; } voidprint();};成員函數(shù)在類體外定義voidStudent::init(intnumber1,char*name1,floatscore1){作用域解析運算符

number=number1; strcpy(name,name1); score=score1;}voidStudent::print(){ cout<<”number:”<<number<<”name:”<<name<<”score:”<<score<<’\n’;}成員函數(shù)在類體內(nèi)外的區(qū)別一般情況下,在類體中僅給出成員函數(shù)的原型,而把成員函數(shù)的定義放在類體之外實現(xiàn)。這種將類的成員函數(shù)的聲明(declaration)和定義(definition)進行分離的方式有很多好處類體內(nèi)定義的成員函數(shù)在編譯時是以內(nèi)聯(lián)函數(shù)處理的,只有那些非常簡短的函數(shù)才在類體中直接定義。2.1.4

C++中對象的定義和使用在C++語言中,類是用戶定義的一種新類型,所以可以象聲明普通變數(shù)一樣來建立對象。在C++語言中,類與對象的關(guān)係就好象整型int和整型變數(shù)i之間的關(guān)係一樣。注意:所有類對象都共用它們的成員函數(shù),但是,每一個對象都建立並保持自己的數(shù)據(jù)。對象的數(shù)據(jù)成員,在C++中稱為實例變數(shù)。創(chuàng)建對象的方法之一在定義類時同時創(chuàng)建對象,例如:classdate{intmonth,day,year;public:voidsetdate(int,int,int);voidprint();intgetyear();intgetmonth();intgetday();}tt;//同時創(chuàng)建對象tt。創(chuàng)建對象的方法之二在定義類後在創(chuàng)建對象,例如:Datadate1,date2;對象的使用對象的性質(zhì)和定義要求將實例變數(shù)隱藏在對象中,對它們的訪問,原則上要通過其介面——共有的成員函數(shù)來進行。訪問對象的成員時,使用“.”運算符:對象名.成員名稱;調(diào)用成員函數(shù)是必須指明對象,事實上,在C++語言中,我們用OOP術(shù)語發(fā)送消息來代替“調(diào)用成員函數(shù)”這個說法。2.1.5

C++中類的介面與實現(xiàn)一般把僅含函數(shù)原型的類聲明部分稱為類的介面(interface),例如:classDate{ intday,month,year;public: voidinit(intdd,intmm,intyy);//initialize voidadd_year(intn); //addnyears voidadd_month(intn);//addnmonths voidadd_day(intn); //addndays}C++中類的介面與實現(xiàn)(續(xù))把類中成員函數(shù)的定義部分稱為類的實現(xiàn)部分(implementation)。例如:voidDate::init(intdd,intmm,intyy){ day=dd; month=mm; year=yy;}inlinevoidDate::add_year(intn){ year+=n;}C++中類的介面與實現(xiàn)(續(xù))C++中的類實現(xiàn)了介面和實現(xiàn)的分離,這樣只要維持介面不變,實現(xiàn)部分可以根據(jù)需要不斷改進,而不影響類的使用。類的介面部分一般存放在擴展名為h的頭檔中,類的實現(xiàn)部分則存放在擴展名為cpp的實現(xiàn)檔中。在cpp檔的開頭要用include將h頭檔包含在其中。這個特徵增強了類模組的獨立性和可重用性(reuse)。設(shè)計一個類(class)時的基本原則在設(shè)計一個新的類(class)類型時的基本原則是將類的複雜的實現(xiàn)細節(jié)(例如用來存儲該類對象的數(shù)據(jù))和正確使用該類所需知道的要素(例如訪問對象數(shù)據(jù)的函數(shù))分離開來。這種分離的最好方式就是通過一個特定的介面來使用該類的數(shù)據(jù)結(jié)構(gòu)和內(nèi)部處理程式。封裝(encapsulation)在進行類定義時,我們把需要提供給類的用戶的在類對象上執(zhí)行的操作聲明為公用的(public),這樣就形成了類的介面。然後按照資訊隱藏(informationhiding)的原則來把類的內(nèi)部數(shù)據(jù)表示和實現(xiàn)細節(jié)聲明為私有的(private),從而完成了封裝(encapsulation)。封裝性及其好處所謂封裝,在面向?qū)ο蟪淌皆O(shè)計中的含義就是包含和隱藏對象資訊,如內(nèi)部數(shù)據(jù)結(jié)構(gòu)和代碼的能力。在C++中封裝是通過類來實現(xiàn)的,即將內(nèi)部的數(shù)據(jù)和代碼聲明為私有的,外界不能直接訪問。封裝將操作對象的內(nèi)部複雜性與應用程式的其他部分隔離開來。換句話說,應用類對象的程式員不需要知道類內(nèi)部的實現(xiàn)細節(jié)就可以使用該類。這是面向?qū)ο蟪淌皆O(shè)計降低複雜性的最主要途徑。2.1.6類聲明與類定義類定義包含兩部分:類頭和類體,類體由一對花括弧包圍起來。一旦到了類體的結(jié)尾,即結(jié)束右邊的花括弧,這時就定義了一個類。一旦定義了一個類,則該類的所有成員就都是已知的,類的大小也是已知的了。類聲明由於歷史的原因,類的定義(classdefinition)也稱為類的聲明(declaration)。但是準確地說,一旦給出了類頭,就聲明了一個類。我們可以聲明一個類但是不定義它。例如:classDate;//Date類的聲明這個聲明向程式引入了一個名字Date,指示Date為一個類類型。類聲明(續(xù))如果還沒有定義類,那麼我們就不能定義這類類型的對象但是,我們可以聲明指向這種類型對象的指針或者引用。classDate; //Date類的聲明Datepd,&rd;//聲明了指向Date類對象的指針pd和引用rd2.1.7結(jié)構(gòu)struct與類class的比較結(jié)構(gòu)和類的唯一區(qū)別是:在缺省情況下結(jié)構(gòu)內(nèi)數(shù)據(jù)成員和成員函數(shù)是公有的public,而類中的數(shù)據(jù)成員和成員函數(shù)是私有的private。可以說C++中的結(jié)構(gòu)是一種特殊的類。類(或者結(jié)構(gòu))的私有成員只能被該類(或者結(jié)構(gòu))的成員函數(shù)訪問,這是C++實現(xiàn)封裝的一種方法。§2.2構(gòu)造函數(shù)和析構(gòu)函數(shù)2.2.1構(gòu)造函數(shù)2.2.2析構(gòu)函數(shù)2.2.3重載構(gòu)造函數(shù)2.2.4組合類和對象成員的初始化2.2.1構(gòu)造函數(shù)constructor構(gòu)造函數(shù)是類的一種特殊成員函數(shù),用來為對象進行初始化。構(gòu)造函數(shù)的函數(shù)名與類名相同。構(gòu)造函數(shù)的例子1classDate{

intday,month,year;

Date(intdd,intmm,intyy);//constructor};//構(gòu)造函數(shù)名與類名相同voidDate::Date(intdd,intmm,intyy){ day=dd; month=mm; year=yy;}用來為對象進行初始化。構(gòu)造函數(shù)的例子2classStudent{private: intnumber; charname[15]; floatscore;public: Student(intnumber1,char*name1,floatscore1);voidmodify(floatscore1) {score=score1;} voidprint();};構(gòu)造函數(shù)的聲明構(gòu)造函數(shù)的例子2//構(gòu)造函數(shù)的定義Student::Student(intnumber1,char*name1,floatscore1){ number=number1; strcpy(name,name1); score=score1;}構(gòu)造函數(shù)(續(xù))構(gòu)造函數(shù)可以有任一類型的參數(shù),但不能具有返回類型。當定義一個對象時,系統(tǒng)自動調(diào)用構(gòu)造函數(shù)進行初始化。構(gòu)造函數(shù)與其它函數(shù)一樣可以重載也可以有缺省參數(shù)。在對象生成的時候自動執(zhí)行初始化,這會消除任何錯誤地不執(zhí)行初始化的可能。這是C++面向?qū)ο蟪淌皆O(shè)計幫助減少複雜性的另一途徑。有缺省參數(shù)的構(gòu)造函數(shù)classcomplex{private:doublereal;doubleimage;public:voidcomplex(doubler=0.0,doublei=0.0){real=r;image=i;}doublerealcomplex(){returnreal;}…;};缺省參數(shù)2.2.2析構(gòu)函數(shù)析構(gòu)函數(shù)的作用與構(gòu)造函數(shù)正好相反,當對象被刪除時,利用析構(gòu)函數(shù)進行一些善後處理。一般情況下析構(gòu)函數(shù)執(zhí)行構(gòu)造函數(shù)的逆操作,例如可以利用析構(gòu)函數(shù)來釋放構(gòu)造函數(shù)所動態(tài)申請的記憶體空間。析構(gòu)函數(shù)的名稱與其類名稱相同,並在名稱的前邊加~(鍵盤上的波浪符號)符號。一個類中只能有一個析構(gòu)函數(shù)。(不能重載)析構(gòu)函數(shù)不允許有返回值,並且析構(gòu)函數(shù)不允許帶參數(shù)。參見【例2.7】。構(gòu)造函數(shù)和析構(gòu)函數(shù)的例子//構(gòu)造函數(shù)的定義Student::Student(intnumber1,char*name1,floatscore1){ number=number1; name=newchar[strlen(name1)+1];//申請動態(tài)記憶體單元

strcpy(name,name1); score=score1;}//析構(gòu)函數(shù)的定義Student::~Student(){

delete[]name;//釋放動態(tài)記憶體單元}2.2.3重載構(gòu)造函數(shù)構(gòu)造函數(shù)與其它函數(shù)一樣可以重載也可以有缺省參數(shù)。要重載類的構(gòu)造函數(shù),只需要在類中聲明構(gòu)造函數(shù)的不同函數(shù)原型並且定義相關(guān)的函數(shù)體。重載構(gòu)造函數(shù)主要有三個原因

1.為了獲得靈活性:提供給用戶多種初始化對象的選項。2.為了支持數(shù)組:要聲明一個類的對象數(shù)組則該類應具有一個不帶參數(shù)的構(gòu)造函數(shù)。3.為了自定義複製構(gòu)造函數(shù),將對象進行準確的複製(拷貝):參見第5章堆與複製構(gòu)造函數(shù)。

重載構(gòu)造函數(shù)例一classDate{ intd,m,y;public://... Date(int,int,int);//day,month,year Date(int,int);//day,month,today’syear Date(int);//day,today’smonthandyear Date();//defaultDate:today Date(constchar*);//dateinstringrepresentation};為了獲得靈活性:提供給用戶多種初始化對象的選項2.2.4組合類和對象成員的初始化當一個類的對象作為一個類的成員時,稱為該類的對象成員。使用對象成員著重要注意的問題是一個類的內(nèi)部對象的初始化問題。類的對象成員初始化#include"iostream.h"classinner_class{ intx;public: inner_class(intz){x=z;} voidwrite(){cout<<x<<endl;}};類的對象成員初始化(續(xù))classouter_class{ inty; inner_classx; inner_classr;public: outer_class(intz); voidwrite(){cout<<y<<endl;} voidwrite_inner_x() {x.inner_class::write();} voidwrite_inner_r() {r.inner_class::write();}};注意:outer_class類對象在通過構(gòu)造函數(shù)進行初始化的同時,也要對其成員對象進行初始化。類的對象成員初始化(續(xù))outer_class::outer_class(intz):x(20),r(-36){y=z;}main(){ outer_classobj(10); obj.write_inner_x(); obj.write_inner_r(); obj.write(); return0;}初始化參數(shù)傳遞鏈初始化和撤銷的順序先裏後外:先調(diào)用對象成員的構(gòu)造函數(shù),再調(diào)用週邊類的成員函數(shù)。雖然對象成員調(diào)用它們類的構(gòu)造函數(shù),但此時寫的是對象的名字,而不是類名。先外後裏:當撤銷一個包含對象成員的對象時,該對象的析構(gòu)函數(shù)將先執(zhí)行,然後再調(diào)用對象成員的析構(gòu)函數(shù)?!纠?.9】對象成員的初始化。//注意:在定義Student類的構(gòu)造函數(shù)時,必須綴上對象成員的名字birthdayStudent::Student(intnumber1,char*name1,floatscore1,intd1,intm1,inty1):birthday(d1,m1,y1)//對象成員birthday的初始化{ number=number1; strcpy(name,name1); score=score1;}2.3類與const軟體工程的歷史經(jīng)驗表明,程式內(nèi)部相當多的隱蔽錯誤是由於無意中修改了某些數(shù)據(jù)的值造成的。對數(shù)據(jù)進行保護是減少程式中的錯誤,提高軟體的可靠性的有效途徑之一。在C++中還廣泛使用const關(guān)鍵字,用來實現(xiàn)對共用數(shù)據(jù)的保護,提高軟體的安全性。2.3.1常成員函數(shù)

ConstantMemberFunctionsclassDate{ intd,m,y;public: intday()const{returnd;} intmonth()const{returnm;} intyear()const; //...};使用const關(guān)鍵字說明的函數(shù)常成員函數(shù)不更新對象的數(shù)據(jù)成員。(只讀函數(shù))常成員函數(shù)(續(xù))inlineintDate::year()const//正確{ returny;}inlineintDate::year()//錯誤{ returny;}const是函數(shù)類型的一個組成部分,因此在實現(xiàn)部分也要帶const關(guān)鍵字。遺漏了const關(guān)鍵字常成員函數(shù)(續(xù))inlineintDate::year()const{ returny++;}將出現(xiàn)編譯錯誤資訊:企圖在常成員函數(shù)中修改對象的數(shù)據(jù)成員。2.3.2常對象constantobject常對象是指對象常量,定義格式如下:<類名>const<對象名>或者

const<類名><對象名>

例如:constDatecd;常對象constantobject(續(xù))必須對常對象進行初始化,而且不能被更新。常對象只能調(diào)用它的常成員函數(shù)。普通的對象既可以調(diào)用它的常成員函數(shù),也可以調(diào)用普通成員函數(shù)。請看下麵的例子:常對象constantobject(續(xù))voidf(Date&d,constDate&cd){ inti=d.year();//ok d.add_year(1);//ok intj=cd.year();//ok cd.add_year(1);//錯誤}常對象不能調(diào)用它的普通成員函數(shù)3.1類與對象3.1.1對象3.1.2類3.1.3對象與類的關(guān)係對象的廣義定義什麼是對象(object)?現(xiàn)實世界中的任何一個事物都可以看成是一個對象。自然的實體:一個人,一輛汽車,一個教師邏輯結(jié)構(gòu):一個銀行帳號,一個學生的學籍檔案,客戶通信錄對象的特性對象是人們要研究的任何事物,其特性是:1、每一個對象必須有一個名字以區(qū)別於其他對象;2、用屬性(或叫狀態(tài))來描述它的某些特徵;3、有一組操作,每一個操作決定對象的一種行為。//這是關(guān)於對象的廣義定義面向?qū)ο蟮南到y(tǒng)中的對象對象是基本的運行時實體,它既包含數(shù)據(jù)(屬性),也包括作用與數(shù)據(jù)的操作(行為)。一個對象把屬性和行為封裝成一個整體。對象是數(shù)據(jù)和對數(shù)據(jù)的操作的結(jié)合體。從程式設(shè)計者來看,對象是一個程式模組;從用戶來看,對象為他們提供了所希望的行為。類的例子人類水果類魚類“類”是對一組具有共同屬性特徵和行為特徵的對象的抽象。OOP中類的例子classStudent{ intnumber; char*name; floatscore;public:

Student(intnumber1,char*name1,floatscore1); ~Student(); voidmodify(floatscore1); voidprint();};屬性操作什麼是類(class)?在C++語言中,我們通過定義新的數(shù)據(jù)類型來構(gòu)成類。在新的數(shù)據(jù)類型中,既包含數(shù)據(jù)內(nèi)容又包含對數(shù)據(jù)的操作。一個類所包含的方法和數(shù)據(jù)描述一組對象的共同行為和屬性。什麼是類(class)?一個類定義了一個大體上相似的對象。把一組對象的共同特性加以抽象並存儲在一個類中的能力,是面向?qū)ο蠹夹g(shù)最重要的一點。對象與類的關(guān)係類是對一組性質(zhì)相同的對象的描述,是對一組數(shù)據(jù)和方法的封裝。對象則是類的具體化,是類的實例??梢赃@樣定義對象:對象是類的一個實例,包括了數(shù)據(jù)和過程。3.2消息和方法3.2.1消息3.2.2方法消息Message消息是要求某個對象執(zhí)行其中某個功能操作的規(guī)格說明。OOP中的一條消息由消息選擇器(“消息操作”或“消息名”)及若干個參數(shù)和接受消息的對象三部分組成,例如:student1.modify(score1);消息的例子接受消息的對象參數(shù)↓↓student1.modify(score1);↑

消息名發(fā)送消息與函數(shù)調(diào)用的比較1) 函數(shù)調(diào)用可以帶或不帶參量,但消息至少帶一個參量(對象名或?qū)ο笾羔槪?;它指明接受該消息的對象。消息選擇器則告訴對回應作些什麼。2) 消息名(消息選擇器或消息操作)類似於函數(shù)名,但二者之間的本質(zhì)差別在於:函數(shù)名僅代表一段可執(zhí)行的代碼,而消息名的具體功能的實現(xiàn)取決於所接受消息的對象。發(fā)送消息與函數(shù)調(diào)用的比較(續(xù))3) 函數(shù)調(diào)用是過程式(面向過程)的即“如何做(Howtodo)”,而消息則是通知式(面向?qū)ο螅┑?,即告訴對象“做什麼(Whattodo)”,具體“如何做(Howtodo)”由對象根據(jù)接受到的消息自行確定。lst.sort();其中,lst代表一個鏈表對象,sort是表示排序的消息名。方法(method)“方法”對應於對象的行為(能力),即它是實現(xiàn)對象所具有的功能操作的代碼段。在C++程式中,方法即是類中定義的成員函數(shù),它是該類對象所能執(zhí)行的操作的演算法實現(xiàn)。通常每個類中包含多個方法(即C++的成員函數(shù)),每個方法由方法名(函數(shù)名+參數(shù)表)和說明該成員函數(shù)的演算法實現(xiàn)的一段代碼所組成。方法的例子voidStudent::print(){ cout<<”number:”<<number<<”name:”<<name<<”score:”<<score<<’\n’;}方法是與對象相連決定怎麼做的操作執(zhí)行代碼,所以方法是實現(xiàn)每條消息具體功能的手段。3.3什麼是面向?qū)ο蟪淌皆O(shè)計3.3.1結(jié)構(gòu)化程式設(shè)計方法3.3.2面向?qū)ο蟪淌皆O(shè)計方法表3.1程式設(shè)計方法的發(fā)展過程1957~1972:面向過程的程式設(shè)計1968~1990:面向過程的結(jié)構(gòu)化程式設(shè)計1984~今:面向?qū)ο蟮某淌皆O(shè)計結(jié)構(gòu)化程式設(shè)計的基本思想按功能劃分模組,分而治之。分解系統(tǒng)時按照自頂向下的順序,逐步求精。設(shè)計時使各模組間的關(guān)係盡可能簡單,功能上相對獨立,從而可單獨驗證模組的正確性。結(jié)構(gòu)化程式的組成

主控模組功能模組1功能模組7功能模組2功能模組3功能模組6功能模組5功能模組4圖3.3結(jié)構(gòu)化程式的組成結(jié)構(gòu)化程式設(shè)計方法的基本特點把數(shù)據(jù)結(jié)構(gòu)和處理數(shù)據(jù)的操作過程分離為相互獨立的實體。用數(shù)據(jù)表達實際問題中的資訊;程式代碼則實現(xiàn)用於處理加工這些數(shù)據(jù)的演算法。簡而言之,就是數(shù)據(jù)和操作代碼分離。

數(shù)據(jù)和操作代碼分離產(chǎn)生的問題給程式員增加了負擔:必須確保數(shù)據(jù)和代碼匹配。當數(shù)據(jù)結(jié)構(gòu)改變時,所有相關(guān)的處理過程都要進行相應的修改。可維護性低。即使要對不同的數(shù)據(jù)格式(結(jié)構(gòu)和類型)作同樣的處理計算,也必須編寫不同的程式??芍赜眯圆缓?。面向?qū)ο蟪淌皆O(shè)計用面向?qū)ο蟪淌皆O(shè)計語言中的對象和類直接模擬現(xiàn)實世界中的對象,將問題空間直接映射到軟體空間。從而設(shè)計出盡可能直接、自然地表示問題求解方法的軟體。面向?qū)ο蟮倪@種思維方式符合人類的自然思維習慣,使我們能夠在程式中自然地描述現(xiàn)實世界的實體和問題,增強了程式代碼的可讀性,有利於控制軟體的複雜性。模組化將一個複雜的大規(guī)模軟體系統(tǒng)劃分成幾個規(guī)模較小、相對簡單的模組,即分而治之。面向?qū)ο蟪淌皆O(shè)計方法是按對象來劃分。面向?qū)ο蟮能涹w系統(tǒng)由對象組成,對象之間通過消息傳遞互相聯(lián)繫,如圖3.4所示。面向?qū)ο蟮能涹w系統(tǒng)的組成

對象1對象2對象3對象4圖中箭頭表示對象之間的消息傳遞對象作為程式模組面向?qū)ο蟮能涹w系統(tǒng)中每一個模組都是高度獨立的對象,而對象是比功能模組粒度更大的模組。對象是由數(shù)據(jù)和對數(shù)據(jù)的操作(代碼)形成的一個整體。面向?qū)ο蟪淌皆O(shè)計採用封裝的辦法,使對象的內(nèi)部實現(xiàn)與外界隔離,實現(xiàn)了資訊隱藏,從而提供了更理想的模組化機制,顯著地減少了程式模組間的相互干擾和依賴性。

數(shù)據(jù)抽象技術(shù)

將數(shù)據(jù)和對數(shù)據(jù)的操作封裝在一起,作為一個相互依存、不可分割的整體——對象來處理,它採用數(shù)據(jù)抽象和資訊隱藏技術(shù)。它將具有相同特徵的對象抽象成一個新的數(shù)據(jù)類型——類,並且考慮不同對象之間的聯(lián)繫和對象類的重用性3.4數(shù)據(jù)抽象3.4.1什麼是抽象?3.4.2數(shù)據(jù)抽象和抽象數(shù)據(jù)類型抽象性的例子classstudent{ intnumber; char*name; floatscore;public: student(intnumber1,char*name1,floatscore1); ~student(); voidmodify(floatscore1); voidprint();};抽象是有選擇地忽略。抽象性(Abstraction)抽象是對複雜的現(xiàn)實世界的簡明的表示。抽象強調(diào)了我們所關(guān)心的(感興趣)的資訊,而將我們不關(guān)心的其他資訊忽略。名家之言E.Dijkstra:“設(shè)計並實現(xiàn)一個大規(guī)模的軟體的中心問題是怎樣減小複雜度,一個途徑就是通過抽象”。BjarneStroustrup說:“在C++語言中,我一直在努力提高程式設(shè)計的抽象層次”。抽象數(shù)據(jù)類型一個值集和作用在值集上的操作集

C++語言中的一個類就是一個抽象數(shù)據(jù)類型每個抽象數(shù)據(jù)類型自成一個模組,模組的介面和內(nèi)部實現(xiàn)分離開來,使用模組的應用程式員只需要知道如何使用該模組,而不必知道模組內(nèi)部是如何實現(xiàn)的,也就是說,可以忽略模組內(nèi)部的實現(xiàn)細節(jié)。

3.5封裝性和資訊隱藏所謂封裝(encapsulation),就是包含和隱藏對象資訊,如內(nèi)部數(shù)據(jù)結(jié)構(gòu)和代碼的能力。在面向?qū)ο蟮某淌街校ㄟ^創(chuàng)建對象將代碼和數(shù)據(jù)捆綁在一起,並且在對象中包含了所有必需的代碼和數(shù)據(jù)。對象是支持封裝的元素。一個程式中的對象把現(xiàn)實世界中的實體的屬性和行為封裝成一個整體。資訊隱藏(informationhiding)

封裝的好處封裝性降低了程式設(shè)計的複雜度。

封裝將操作對象的內(nèi)部複雜性與應用程式的其他部分隔離開來。應用程式員只需要通過對象的介面來操作對象完成特定的任務,而不需要知道對象內(nèi)部複雜的細節(jié)。

封裝的好處(續(xù))提高了代碼的安全性和可靠性;通過類實現(xiàn)封裝,集中和統(tǒng)一了對類中數(shù)據(jù)成員的所有操作,從而可避免因分散操作造成的錯誤。能有效提到程式模組的獨立性、可重用性和可維護性;只要類的介面(即類的共有部分)保持不變,類的結(jié)構(gòu)部分的任何變化(包括數(shù)據(jù)結(jié)構(gòu)和演算法)都不會對使用該類的根源程式有所影響,根源程式可以不做任何修改。面向?qū)ο蟪淌皆O(shè)計的主要特徵抽象性封裝性繼承性多態(tài)性3.6繼承性與軟體重用面向?qū)ο蟪淌皆O(shè)計的第二個主要特徵就是繼承性,繼承的目的就是為了重用(reuse)。

繼承,就是在一個已有的類的基礎(chǔ)上創(chuàng)建一個新類

,這個新類獲得了已有類的數(shù)據(jù)和操作代碼,並且新類可以增加新的數(shù)據(jù)和操作代碼。

繼承與派生問題舉例派生類的概念在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)生新類的過程稱為派生。被繼承的已有類稱為基類(或父類)。派生出的新類稱為派生類(或子類)。參見圖3.5類的繼承

繼承與派生的目的繼承的目的:實現(xiàn)代碼重用。派生的目的:當新的問題出現(xiàn),原有程式無法解決(或不能完全解決)時,需要對原有程式進行改造。C++中類的繼承層次自然地表達了人們分析問題時所用的分類結(jié)構(gòu)。大大改善了軟體系統(tǒng)的可理解性和可維護性。

繼承的好處(1)繼承性很好地實現(xiàn)了代碼的重用。(2)能改進軟體系統(tǒng)的可維護性。(3)繼承性使已有的程式庫具有清晰的層次結(jié)構(gòu)關(guān)係。3.7多態(tài)性廣義多態(tài)性:自然語言中的多態(tài)性;面向?qū)ο蟪淌皆O(shè)計中的多態(tài)性什麼是多態(tài)性?(廣義)polymorphism,“manyforms”:即多種形態(tài)在自然語言中,多態(tài)性即是“一詞多義”;更準確地說,多態(tài)性是指相同的動詞作用到不同類型的對象上,例如:

駕駛摩托車 駕駛汽車 駕駛飛機 駕駛輪船駕駛太空船什麼是多態(tài)性?(OOP)當不同對象接受到相同的消息產(chǎn)生不同的動作,這種性質(zhì)稱為多態(tài)性。通俗地說,多態(tài)性是指用一個名字定義不同的函數(shù),這些函數(shù)執(zhí)行不同但又類似的操作,即用同樣的介面訪問功能不同的函數(shù),從而實現(xiàn)“一個介面,多種方法”。多態(tài)性的例子在C語言中,由於不支持多態(tài),求絕對值的動作要求三個不同的函數(shù)名字:

abs(),labs(),fabs()分別用來求整數(shù),長整數(shù)、浮點數(shù)的絕對值。在C++語言中,由於支持多態(tài),求絕對值的動作可以只用一個函數(shù)名:abs()應用多態(tài)性的好處多態(tài)應用於OOP的目的是允許用一個名字來指定動作的一般類(即邏輯上相似的動作)。從而帶來以下的好處:提高了處理問題的抽象級別;降低了程式設(shè)計時的複雜性;增強了軟體的靈活性。面向?qū)ο蟪淌皆O(shè)計的優(yōu)越性重用性:有利於軟體生產(chǎn)率的提高;符合人類的自然思維習慣,能夠自然地描述現(xiàn)實世界的實體和問題:有利於控制軟體的複雜性;更好的模組化,便於多人分工和合作開發(fā)軟體;編寫的代碼有更好的可維護性;3.8面向?qū)ο蟮某淌皆O(shè)計語言3.8.1對象程式設(shè)計語言的發(fā)展概況3.8.2幾種典型的面向?qū)ο蟪淌皆O(shè)計語言幾種典型的OOPLSmalltalkC++JavaC#

4.1對象數(shù)組(Objectarrays)定義: 類名數(shù)組名[元素個數(shù)];例如:StudentaSA[10];//一個學生類對象數(shù)組通過下標訪問方法: 數(shù)組名[下標].成員名;例如:aSA[j].print();對象數(shù)組初始化數(shù)組中每一個元素對象被創(chuàng)建時,系統(tǒng)都會調(diào)用構(gòu)造函數(shù)類初始化該對象。通過初始化列表賦值。例:

LocationA[2]={Location(1,2),Location(3,4)};如果沒有為數(shù)組元素指定顯式初始值,數(shù)組元素使用缺省值初始化(調(diào)用缺省構(gòu)造函數(shù))。當數(shù)組中每一個對象被刪除時,系統(tǒng)都要調(diào)用一次析構(gòu)函數(shù)。數(shù)組元素所屬類的構(gòu)造函數(shù)沒有自定義構(gòu)造函數(shù)時,則採用缺省構(gòu)造函數(shù)。各元素對象的初值要求為相同的值時,可以定義出具有缺省形參值的構(gòu)造函數(shù)。各元素對象的初值要求為不同的值時,需要定義帶形參(無缺省值)的構(gòu)造函數(shù)。如果需要定義動態(tài)數(shù)組,需要一個無參構(gòu)造函數(shù)。對象數(shù)組例子#include<iostream.h>classsamp{inta,b;public:samp(intn,intm){a=n;b=m;}intget_a(){returna;}intget_b(){returnb;}};對象數(shù)組例子(續(xù))main(){sampob[4][2]={samp(1,2),samp(3,4),samp(5,6),samp(7,8),samp(9,10),samp(11,12),samp(13,14),samp(15,16),};inti;對象數(shù)組例子(續(xù))

for(i=0;i<4;i++){cout<<ob[i][0].get_a();cout<<ob[i][0].get_b()<<"\n";cout<<ob[i][1].get_a();cout<<ob[i][1].get_b()<<"\n";}cout<<"\n";return0;}4.2指向?qū)ο蟮闹羔樋梢远x指向?qū)ο蟮闹羔?,在運用對象的指針的時候,對象的成員將用箭頭運算符(→)而不是點運算符(.)引用。對象的指針演算法與其它數(shù)據(jù)類型的指針演算法相同:它被與對象相聯(lián)系的處理。例如:當對象指針增加的時候,它指向下一個對象;當對象指針減少的時候,它指向前一個對象。對象指針的用法

intmain(){

Circlec1(3),*pc;//pc為指向圓形Circle類對象的指針

pc=&c1; //將對象c1的地址賦給對象指針pc,使其指向圓形對象c1

cout<<c1.GetArea()<<endl; //通過對象名訪問對象的方法

cout<<pc->GetArea()<<endl;//通過對象指針訪問對象的方法

return0;}對象指針與對象數(shù)組#include"student.h"intmain(){… Student*sp=aSA; //給指針賦初值

for(inti=0;i<4;i++,sp++)sp->print();//指針加1後,指向下一個對象

sp=sp-3; //指針減3後,指針向前移動三個對象

sp->modify(87); sp->print(); return0;}4.3this指針對象是由數(shù)據(jù)和操作構(gòu)成的一個整體,即使同一類的不同對象的操作也是相互獨立的,各占不同的記憶體空間。但是,在C++實現(xiàn)中,這種處理方案太浪費記憶體空間。同類的對象能否共用該類成員函數(shù)的同一個實例呢?myBirthday.set(31,12,1997);nationalDay.set(1.10,1949);voidDate::Set(intD,intM,inty){day=D;month=M;year=Y;}那麼,此時電腦怎麼能區(qū)分該函數(shù)是作用在哪個對象上呢?解決方案C++在編譯時,自動在每個成員函數(shù)中的第一個參數(shù)位置增加:

X*constthis;

當對象調(diào)用該函數(shù)時,編譯器自動將該對象的指針作為實參傳遞給相應的函數(shù),這樣就可解決上述問題:voidDate::Set(Date*constthis,intD,intM,intY){this->day=D;this->month=M;this->year=Y;}

注:程式員不能將this指針的說明寫在函數(shù)中C的結(jié)構(gòu)體struct與C++的struct的比較C語言的結(jié)構(gòu)體中數(shù)據(jù)與操作是分離的

在C++語言中將數(shù)據(jù)與操作封裝在一個結(jié)構(gòu)體中

structStudent{ intnumber; charname[15]; floatscore;};數(shù)據(jù)成員structStudent{intnumber;charname[15];floatscore;voiddisplay(Student*this)//函數(shù)成員{ cout<<”number:”<<this->number; cout<<”name:”<<this->name; cout<<”score:”<<this->score<<endl;}};/*獨立函數(shù)display*/voiddisplay(Student*stu){ printf(”number:%d”,stu->number); printf(”name:%s”,stu->name); printf(”score:%f\n”,stu->score);}數(shù)據(jù)成員this指針this指針是由C++編譯器自動產(chǎn)生而使用的一個隱含指針,類成員函數(shù)使用該指針來存取對象的數(shù)據(jù)成員。

定義同一類的多個對象時,每個對象擁有自己的數(shù)據(jù)成員但它們共用一份成員函數(shù),當成員函數(shù)存取對象的數(shù)據(jù)時它們使用this指針,通過this指針指向不同對象來決定使用哪一個對象的數(shù)據(jù)成員。this指針是如何在“幕後”工作?例如complex類中的init函數(shù):voidinit(doubler,doublei){real=r;image=i;}C++編譯器在編譯這個函數(shù)時自動插入this指針:voidinit(complex*this,doubler,doublei){this->real=r;this->image=i;}this指針的顯式使用this指針是系統(tǒng)的一個內(nèi)部指針,通常以隱式方式使用,但也可以為程式員所使用,例如,當運算符重載和建立鏈表時this指針顯得十分重要。參見雙向鏈表This指針的顯式用法顯式地使用this指針,還可以使C++的編譯器將同名的參數(shù)與數(shù)據(jù)成員區(qū)分開來:voidDate::Set(intday,intmonth,intyear){this->day=day;this->month=month;this->year=year;}4.4對象的賦值如果兩個對象屬於同一種類型,那麼我們可以將其中的一個對象的值(屬性值)賦給另一個對象。在默認情況下,當將一個對象賦值給另一個對象時,第一個對象的數(shù)據(jù)將被按位複製到第二個對象中。對象賦值的例子【例4.4】

intmain(){Rectanglerect1(10,20),rect2(0,0);

溫馨提示

  • 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

提交評論