c++基礎(chǔ)教案課件_第1頁
c++基礎(chǔ)教案課件_第2頁
c++基礎(chǔ)教案課件_第3頁
c++基礎(chǔ)教案課件_第4頁
c++基礎(chǔ)教案課件_第5頁
已閱讀5頁,還剩135頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

目錄第一節(jié)c++概述第二節(jié)函數(shù)第三節(jié)類和對象第四節(jié)友元和重載第五節(jié)模板第六節(jié)繼承c++基礎(chǔ)教案第一節(jié)c++概述main()函數(shù)標(biāo)準(zhǔn)輸入輸出流exit語句數(shù)據(jù)類型標(biāo)準(zhǔn)庫string類型引用類型指針和const限定符動態(tài)內(nèi)存分配c++基礎(chǔ)教案1.1main()函數(shù)intmain(){……return0;}每個c++程序必須含有main()函數(shù),且main函數(shù)是唯一被操作系統(tǒng)顯式調(diào)用的函數(shù)定義函數(shù)必須制定4個元素:返回類型、函數(shù)名、形參表、函數(shù)體。操作系統(tǒng)通過main的返回值來確定程序是否成功執(zhí)行完畢,返回0表示程序成功執(zhí)行完畢,通常非0表示有錯誤出現(xiàn)c++基礎(chǔ)教案1.2標(biāo)準(zhǔn)輸入輸出流C++沒有直接定義進(jìn)行輸入/輸出的任何語句,這個功能由標(biāo)準(zhǔn)庫iostream.h提供。包含兩個類:輸入流istream和輸出流ostream.#include<iostream>usingnamespacestd;標(biāo)準(zhǔn)庫中的四個IO對象cin標(biāo)準(zhǔn)輸入(如鍵盤),為istream對象cout標(biāo)準(zhǔn)輸出(如顯示屏),為ostream對象cerr標(biāo)準(zhǔn)錯誤,用于輸出警告和錯誤信息,為ostream對象clog用于產(chǎn)生程序執(zhí)行的一般信息,為ostream對象c++基礎(chǔ)教案cin讀入流(由鍵盤輸入)作用從鍵盤取得數(shù)據(jù)送至內(nèi)存,與>>一起使用結(jié)合方向為自左向右例如:intv1,v2;cin>>v1>>v2;從流中讀取信息時,輸入流緩沖指針跟蹤最后一個讀入到流的字符,每次嘗試從流獲取信息時,都從指針的當(dāng)前位置開始cin自動跳過空白字符(whitespace)返回值為左操作數(shù)c++基礎(chǔ)教案用cout寫入到流(輸出到屏幕)cout必須與輸出操作符<<一起使用,結(jié)合方向為自左向右例如:cout<<"Entertwonumbers"<<endl;cout<<dec<<x;(hex/oct)作用將右操作數(shù)插入到cout中,可同時接受不同類型的數(shù)據(jù)輸出,所以可有多個<<操作符,把信息寫入流時,把信息添加到流的末尾,相當(dāng)于從左到右輸出endl(endofline)為操縱符,具有換行效果,并刷新與設(shè)備相關(guān)聯(lián)的緩沖區(qū),刷新后用戶可立即看到寫入到流中的輸出。注:忘記刷新可能會造成輸出停留在緩沖區(qū),建議在程序員調(diào)試過程中,這些語句都應(yīng)刷新輸出流iomanip.h中,setw(n):為后面的輸出項預(yù)留n列

c++基礎(chǔ)教案1.3exit()語句形式:exit(interger_value);執(zhí)行exit語句時,程序立即終止。一般來說,如果因為一個錯誤而調(diào)用exit,就使用1,其他情況使用0。該函數(shù)在頭文件cstdlib中,所有要有預(yù)編譯命令#include<cstdlib>usingnamespacestd;c++基礎(chǔ)教案1.4內(nèi)置數(shù)據(jù)類型常量宏常量:#definePI3.1415926

系統(tǒng)不為其分配內(nèi)存,只是簡單的字符串替換const常量:const類型常量標(biāo)識符=值;

常量定義后不能修改,所以必須初始化

例如:

constdoublePI=3.1415926;系統(tǒng)為PI分配內(nèi)存單元兩種常量的比較const常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型;編譯器可以對const常量進(jìn)行類型合法性檢查,而對宏常量僅僅是字符的替換,沒有合法性檢查,并且在字符替換的時候可能產(chǎn)生意想不到的錯誤c++中,const常量完全可以取代宏常量c++基礎(chǔ)教案布爾類型bool,它的值只有兩個true和false可以將算術(shù)類型的任何值賦給bool對象。0代表false非0代表true初始化:創(chuàng)建對象并給它賦初值(賦值指擦除對象的當(dāng)前值并用新值代替)有兩種形式:復(fù)制初始化:用等號intval=1024;

直接初始化:初始化式放在括號中

intval(1024);通常在一個對象首次使用的地方定義該對象c++基礎(chǔ)教案1.5標(biāo)準(zhǔn)庫string類型#include<string>usingnamespacestd;string對象的定義和初始化strings2(s1);//s1為string對象或字符串字面值strings3(n,'c');//s3為n個c注意:字符串字面值和標(biāo)準(zhǔn)庫string類型不是同一類型string對象的讀寫輸入:cin>>s;

//從第一個非空字符讀至下一個空白字符讀入一行g(shù)etline(cin,line);兩個參數(shù):輸入流對象和string對象功能:從輸入流的中讀取內(nèi)容到line中,換行符是該行的結(jié)束標(biāo)志注:getline()不忽略開頭的換行符,但line并不保存換行符,即若開頭遇換行符,line為空string輸出:cout<<s<<endl;c++基礎(chǔ)教案#include<iostream>#include<string>usingnamespacestd;intmain(intargc,char*argv[]){stringstr;cout<<"Inputastring"<<endl;cin>>str;//輸入str的時候,只要遇到了空格,就會結(jié)束輸入

cout<<str<<endl;cout<<"Inputalineusinggetline"<<endl;getline(cin,str);cout<<str<<endl;return(0);}在用getline()之前已經(jīng)用cin>>str;輸入了一次回車,這個語句遇到回車就結(jié)束,這樣,回車符也跟著到了內(nèi)存,到用getline()再輸入時,內(nèi)存里第一個字符就是回車,所以getline()一讀到這個回車就結(jié)束了,所以getline(cin,str);不起作用。解決:處理掉cin>>str;遺留的回車符,可以在該語句下加一句:getchar();//吸收內(nèi)存里的回車符c++基礎(chǔ)教案string對象的操作s.empty();若字符串為空,返回trues.size();返回s中字符的個數(shù)s[n];返回s中位置為n的字符s1==s2;比較,所有的比較運算符都可以使用s1+=s2;連接s1=s2;賦值,string類型可以和字符串字面值連接,賦給string類型,但是,+操作符的左右操作數(shù)必須至少有一個string類型

strings="hello"+","+s1;×c++基礎(chǔ)教案1.6引用類型引用就是對象的另一個名字,主要用于函數(shù)的形參引入voidsa,intb){inttemp=a;a=b;b=temp;}intmain(){intx=10,y=20;………s);}形參與實參有各自不同的內(nèi)存空間,若實參是一個復(fù)雜對象,重新分配內(nèi)存會引起程序執(zhí)行效率大大下降形參對實參為值傳遞,對形參的任何改變不會引起實參值的改變c++基礎(chǔ)教案1.6.1非const引用引用就是某一變量(目標(biāo))的一個別名,對引用的操作與對變量直接操作完全一樣。聲明:類型標(biāo)識符

&引用名=目標(biāo)變量名;

inta;int&ra=a;//定義引用ra,它是變量a的引用(別名)(1)&在此不是求地址運算,而是起標(biāo)識作用。(2)聲明引用時,必須同時對其進(jìn)行初始化。(3)引用聲明完畢后,相當(dāng)于目標(biāo)變量名有兩個名稱,不能再把該引用名作為其他變量名的別名。(4)聲明一個引用,不是新定義了一個變量,它只表示該引用名是目標(biāo)變量名的一個別名,它本身不是一種數(shù)據(jù)類型,因此引用本身不占存儲單元。故:對引用求地址,就是對目標(biāo)變量求地址。&ra與&a相等。

c++基礎(chǔ)教案非const引用intival=1024;1.引用必須在定義時初始化,int&refval=ival;一旦綁定到某對象不可以將引用int&refval1;×綁定到另一對象int&refval2=refval;×2.不能定義引用類型的引用,int&ref1=4;×必須用與該變量同類型對象初始化int&ref2=ival+5;

×3.引用對應(yīng)的值必須具有相應(yīng)的內(nèi)存空間,以便對這個空間進(jìn)行引用。常量、表達(dá)式、引用不能賦給引用例:inti=5;

intj=6;

int&k=i;

k=j;

//k和i的值都變成了6;c++基礎(chǔ)教案1.6.2const引用格式:

const類型標(biāo)識符

&引用名=目標(biāo)變量名;

用這種方式聲明的引用,不能通過引用對目標(biāo)變量的值進(jìn)行修改,從而使引用的目標(biāo)成為const,達(dá)到了引用的安全性。inta;

constint&ra=a;

ra=1;//錯誤

a=1;//正確引用型參數(shù)應(yīng)該在能被定義為const的情況下,盡量定義為const。

c++基礎(chǔ)教案

對const對象的引用constintival=1024;inti=34;constint&refval=ival;refval=512;×int&ref2=ival;×

constint&ref3=42;constint&ref=i;constint&ref4=ref3+3;

refval是對const型的引用,所以任何對refval的賦值都是非法const對象必須用const引用const引用可以綁定到相關(guān)的類型的對象,或綁定到右值c++基礎(chǔ)教案1.6.3指針和引用的比較指針和引用都可間接訪問另一個值,但是1、引用總是指向某個對象,定義時必須初始化。指針則可以在任何時候被初始化2、引用一旦被初始化,就不能改變引用的關(guān)系而指針則可以隨時改變所指向的對象3、賦值:引用即為別名,給引用賦值修改的是該引用所關(guān)聯(lián)的對象的值(非const引用)而指針可以更改其指向的對象,也可以更改所指向的對象的值4、不能有NULL引用,引用必須與合法的存儲單元關(guān)聯(lián),而指針則可以是NULLc++基礎(chǔ)教案1.7指針和const限定符使用const修飾指針時,由于const的位置不同,而含意不同。

1.7.1指向const對象的指針指向const的指針,不可以通過該指針修改對象,但可以其他方式修改doubledval=3.14,pi=3.1415;constdouble*ptr=&dval;

//const限定了指針?biāo)傅膶ο箢愋?,非ptr*ptr=3.1415;//不合法指針?biāo)傅膶ο蟛荒芨?/p>

ptr=π//合法,指針值可變

dval=3.1415;//合法c++基礎(chǔ)教案若一個指針是指向const對象,則該指針必須具有const特性。例如constdoublepi=3.14159;constdouble*ptr=π//正確double*ptr1=π//錯誤,const對象要用指向const的指針來指向,這樣可以保證既不能通過*ptr,也不能通過pi修改其值指向const的指針常用作函數(shù)的形參,這樣可以確保函數(shù)的實參在函數(shù)調(diào)用過程中不被修改voiduse_ptr(constint*p){……}c++基礎(chǔ)教案1.7.2const指針固定指向一個對象的指針,即指針本身是常量char*constptr1=stringptr1;

//const放在類型說明和變量之間ptr1=stringptr2;//非法,指針本身的值不可改變

*ptr1="m";//合法指針?biāo)傅淖兞康闹悼梢愿淖內(nèi)糁羔樇爸羔標(biāo)赶虻淖兞康闹刀疾豢梢愿?/p>

constchar*constptr=stringptr;c++基礎(chǔ)教案1.8動態(tài)內(nèi)存分配一內(nèi)存分配有三種方式從靜態(tài)存儲區(qū)域分配。內(nèi)存在程序編譯的時候就已經(jīng)分配好,這塊內(nèi)存在程序的整個運行期間都存在。例如全局變量,static變量。棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變量的存儲區(qū)。里面的變量通常是局部變量、函數(shù)參數(shù)等。棧內(nèi)存分配運算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。堆,亦稱動態(tài)內(nèi)存分配。程序在運行的時候用malloc或new申請任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時用free或delete釋放內(nèi)存。動態(tài)內(nèi)存的生存期由我們決定如果程序員沒有釋放掉,那么在程序結(jié)束后,操作系統(tǒng)會自動回收。c++基礎(chǔ)教案1.8.2單個對象的動態(tài)分配與釋放動態(tài)分配:由關(guān)鍵字new及其后面的類型指示符構(gòu)成。該類型指示符可以是內(nèi)置類型或class類型。例:newint;從堆中分配了一個int型的對象。

newStudent; 分配了一個Student類對象。需要注意的是堆中分配的對象沒有名字。new表達(dá)式返回了一個指向該對象的指針,對該對象的全部操作都要通過這個指針間接完成。例如:int*pi=newint;該new表達(dá)式創(chuàng)建了一個int型的對象,由pi指向它。初始化int*pi=newint(0);該語句表示pi指向一個int型的對象,該對象的初始值為0。括號中的表達(dá)式被稱作初始化式c++基礎(chǔ)教案動態(tài)內(nèi)存的釋放與靜態(tài)分配內(nèi)存的對象不同,編譯器不會自動釋放它們所占的內(nèi)存-----除非整個程序結(jié)束。所以當(dāng)動態(tài)分配內(nèi)存的對象完成它的使命,需要被銷毀的時候不能依賴編譯器,而要靠程序員用delete釋放。格式:deletepi;//釋放pi所指向的內(nèi)存空間指針pi本身是個在全局域中聲明的全局對象,它的生命期由編譯器控制。pi的存儲區(qū)在程序開始之前就被分配,一直保持到程序結(jié)束。而pi指向的對象的生命期是由程序員控制的,它是在程序執(zhí)行過程中遇到new表達(dá)式時才被創(chuàng)建,遇到delete表達(dá)式時被銷毀并收回存儲區(qū)c++基礎(chǔ)教案動態(tài)內(nèi)存的釋放delete只能用在指向內(nèi)存是用new動態(tài)分配的指針上,如果將其在指向堆以外內(nèi)存的指針上,會使程序運行期間出現(xiàn)未定義的行為。唯一的例外是,當(dāng)指針指向NULL時,不管指針指向的對象是如何分配內(nèi)存的,都不會引發(fā)麻煩。voidf(){ inti; char*str="asdd"; int*pi=&i; short*ps=NULL; double*pd=newdouble(123.3); deletestr; //危險!str指向的不是動態(tài)對象

deletepi; //危險!pi指向的對象i是一個局部對象

deleteps; //安全!ps指向NULL deletepd; //安全!pd指向一個動態(tài)分配的對象}c++基礎(chǔ)教案常見錯誤1.

忘記了釋放內(nèi)存,造成內(nèi)存泄露。

含有這種錯誤的函數(shù)每被調(diào)用一次就丟失一塊內(nèi)存。剛開始時系統(tǒng)的內(nèi)存充足,你看不到錯誤。終有一次程序突然死掉,系統(tǒng)出現(xiàn)提示:內(nèi)存泄漏(memoryleak)。函數(shù)體內(nèi)的局部變量在函數(shù)結(jié)束時自動消亡。例如p是局部的指針變量,它消亡的時候會讓它所指的動態(tài)內(nèi)存一起消亡。這是錯覺!

voidFunc(void)

{

char*p=(char*)malloc(100);

//動態(tài)內(nèi)存會自動釋放嗎?

}

指針消亡了,并不表示它所指的內(nèi)存會被自動釋放2.

對同一內(nèi)存區(qū)應(yīng)用了多次delete表達(dá)式。這通常發(fā)生在多個指針指向同一個動態(tài)分配對象的時候。若多個指針指向同一對象,當(dāng)通過某一個指針釋放該對象時就會發(fā)生這種情況。3.

內(nèi)存被釋放了,并不表示指針會消亡或者成了NULL指針,形成野指針c++基礎(chǔ)教案野指針因此,當(dāng)程序執(zhí)行deletepi;語句時,pi指向?qū)ο蟮膬?nèi)存被釋放,但指針pi本身的內(nèi)存并沒有受到delete表達(dá)式的影響。在deletepi;之后,pi被稱作空懸指針(俗稱野指針),即指向無效內(nèi)存的指針。空懸指針是錯誤的根源,它很難被檢測到,如果對它進(jìn)行操作將會產(chǎn)生無法預(yù)測的結(jié)果。一個比較好的辦法是在指針?biāo)傅膶ο蟊会尫藕?,馬上將該指針設(shè)置為NULL,這樣可以清楚地表明該指針不再指向任何對象char*p=(char*)malloc(100);

strcpy(p,“hello”);

free(p);

//p所指的內(nèi)存被釋放,但是p所指的地址仍然不變

if(p!=NULL)

//沒有起到防錯作用

{

strcpy(p,“world”);

//出錯

}

c++基礎(chǔ)教案野指針指針操作超越了變量的作用范圍。這種情況讓人防不勝防,示例程序如下:

classA

{

public:

voidFunc(void){cout<<“FuncofclassA”<<endl;}

};

voidTest(void)

{

A

*p;

{

A

a;

p=&a;

//注意a的生命期

}

p->Func();

//p是“野指針”

}c++基礎(chǔ)教案1.8.3數(shù)組的動態(tài)分配與釋放new表達(dá)式也可以在堆中分配數(shù)組。在這種情況下new表達(dá)式中的類型指示符后面必須有一對方括號,里面的值代表數(shù)組的長度,而且該數(shù)值可以是一個復(fù)雜的表達(dá)式。new表達(dá)式返回指向數(shù)組第一個元素的指針。動態(tài)分配數(shù)組只需指定類型和長度格式:newtype[size];//size為數(shù)組元素的長度,可以是任意表達(dá)式。new返回指向新分配數(shù)組的第一個元素的指針。

例如:int*p2;p2=newint[n];delete釋放new分配的存儲空間delete[]p;//[]表明p指向的是動態(tài)存儲區(qū)的數(shù)組,如果遺漏,編譯器無法發(fā)現(xiàn)錯誤c++基礎(chǔ)教案int*pi=newint(1024);//分配單個int型的對象,用1024初始化int*pia=newint[1024];//分配一個含有1024個元素的int型數(shù)組,未被初始化c++基礎(chǔ)教案第二節(jié)函數(shù)參數(shù)傳遞函數(shù)返回值內(nèi)聯(lián)函數(shù)函數(shù)的重載c++基礎(chǔ)教案2.1參數(shù)傳遞C++語言中,函數(shù)的參數(shù)和返回值的傳遞方式有三種:值傳遞、指針傳遞和引用傳遞。在調(diào)用函數(shù)時,對于每一個實參,其類型必須與對應(yīng)的形參類型相同,或可被轉(zhuǎn)換為該形參類型2.1.1普通的非引用形參為傳值調(diào)用,調(diào)用時將實參的值賦給形參,而形參的任何改變不會改變實參voidsp1,intp2){inttemp=p1;p1=p2;p2=temp;}調(diào)用時:inta=5,b=9;

s);//a、b并沒有互換c++基礎(chǔ)教案

指針形參指針傳遞傳遞的是地址,函數(shù)可以通過指針賦值,修改指針?biāo)赶虻膶ο蟮闹祐oids*p1,int*p2){inttemp=*p1;*p1=*p2;*p2=temp;}調(diào)用時怎么寫?1、若要保護(hù)指針指向的對象的值,則形參需定義為指向const對象的指針voiduse_ptr(constint*p){……}在函數(shù)體中,不能通過*p修改p指向的對象的值實參既可以為int*,也可以為constint*類型c++基礎(chǔ)教案2、如果輸入?yún)?shù)采用“值傳遞”,由于函數(shù)將自動產(chǎn)生臨時變量用于復(fù)制該參數(shù),調(diào)用結(jié)束釋放所以該參數(shù)本來就無需保護(hù),沒有必要加const修飾。例如不要將函數(shù)voidFunc1(intx)寫成voidFunc1(constintx)。同理不要將函數(shù)voidFunc2(Aa)寫成voidFunc2(constAa)。其中A為用戶自定義的數(shù)據(jù)類型。對于非內(nèi)部數(shù)據(jù)類型的參數(shù)而言,象voidFunc(Aa)這樣聲明的函數(shù)注定效率比較低。因為函數(shù)體內(nèi)將產(chǎn)生A類型的臨時對象用于復(fù)制參數(shù)a,而臨時對象的構(gòu)造、復(fù)制、析構(gòu)過程都將消耗時間。為了提高效率,可以將函數(shù)聲明改為voidFunc(A&a),因為“引用傳遞”僅借用一下參數(shù)的別名而已c++基礎(chǔ)教案2.1.2引用形參引用的一個重要作用就是作為函數(shù)的參數(shù)。c語言中當(dāng)有大塊數(shù)據(jù)作為參數(shù)傳遞的時候,采用的方案往往是指針,在C++中又增加了一種同樣有效率的選擇(在某些特殊情況下又是必須的選擇),就是引用

voids&p1,int&p2)//形參p1,p2都是引用

{intp;p=p1;p1=p2;p2=p;}當(dāng)調(diào)用該函數(shù),在相應(yīng)的主調(diào)函數(shù)的調(diào)用點處,直接以變量名作為實參進(jìn)行調(diào)用即可,而不需要實參變量有任何的特殊要求。如:對應(yīng)上面定義的swap函數(shù),相應(yīng)的主調(diào)函數(shù)可寫為:c++基礎(chǔ)教案main()

{

inta,b;

cin>>a>>b;//輸入a,b兩變量的值

s);//直接以變量a和b作為實參調(diào)用swap函數(shù)

cout<<a<<''<<b;//輸出結(jié)果

}(1)被調(diào)函數(shù)的形參就成為原來主調(diào)函數(shù)中的實參變量或?qū)ο蟮囊粋€別名來使用,所以在被調(diào)函數(shù)中對形參變量的操作就是對其相應(yīng)的目標(biāo)對象(在主調(diào)函數(shù)中)的操作。

(2)使用引用傳遞函數(shù)的參數(shù),在內(nèi)存中并沒有產(chǎn)生實參的副本,它是直接對實參操作;在傳值調(diào)用中若傳遞的是對象,將調(diào)用拷貝構(gòu)造函數(shù)。因此,當(dāng)參數(shù)傳遞的數(shù)據(jù)較大時,用引用比用一般變量傳遞參數(shù)的效率和所占空間都好。

c++基礎(chǔ)教案三種傳遞方式的比較

值傳遞

voidFunc1(intx)

{x=x+10;

}//形參的使用

intn=0;

Func1(n);//調(diào)用

cout<<“n=”<<n<<endl;

//n=0

指針傳遞

voidFunc2(int*x)

{

(*x)=(*x)+10;

}//形參的使用

intn=0;//調(diào)用

Func2(&n);

cout<<“n=”<<n<<endl;

//n=10c++基礎(chǔ)教案

引用傳遞:

voidFunc3(int&x)

{

x=x+10;

}

intn=0;

Func3(n);

cout<<“n=”<<n<<endl;

//n=10

對比上述三個示例程序,會發(fā)現(xiàn)“引用傳遞”的性質(zhì)象“指針傳遞”,而書寫方式象“值傳遞”。實際上“引用”可以做的任何事情“指針”也都能夠做,為什么還要“引用”這東西?

答案是“用適當(dāng)?shù)墓ぞ咦銮∪缙浞值墓ぷ鳌薄++基礎(chǔ)教案const引用若不希望在函數(shù)體中通過引用來修改實參,可以使用const引用

intsearch(constT&x){……}//x為實參的別名,不用重新開辟空間,且不允許對x進(jìn)行修改

boolisShorter(conststring&s1,conststring&s2){returns1.size()<s2.size();}

一般將不需要修改的引用形參都定義為const引用,而且可以增強(qiáng)其靈活性。(對于非const形參,實參不能為const對象,也不能為字面值常量)c++基礎(chǔ)教案傳遞指向指針的引用voids*&v1,int*&v2)//v1是一個引用,與指向int型對象相關(guān)聯(lián)

{int*v;v=v1;v1=v2;v2=v;}調(diào)用:

int*pa=&a;int*pb=&b;s);c++基礎(chǔ)教案2.2函數(shù)返回值在系統(tǒng)調(diào)用處將函數(shù)的返回值放在一個臨時空間,在調(diào)用的地方使用該返回值(賦給一個變量或進(jìn)行運算),調(diào)用語句執(zhí)行完,釋放臨時空間1)返回引用:沒有復(fù)制返回值,相反返回的是對象本身格式:類型標(biāo)識符&函數(shù)名(形參列表){函數(shù)體}非const引用Chain&Chain::delete(intk){……}const引用:不能更改返回值conststring&shorterString(conststring&s1,conststring&s1){returns1.size()<s2.size()?s1:s2;}一般來說,函數(shù)返回的引用是對函數(shù)的某個參數(shù)的引用,而這個參數(shù)本身也是引用類型。c++基礎(chǔ)教案引用作為返回值,必須遵守以下規(guī)則:

不能返回局部變量的引用。主要原因是局部變量會在函數(shù)返回后被銷毀,因此被返回的引用就成為了"無所指"的引用,程序會進(jìn)入未知狀態(tài)。

conststring&manip(conststring&s){stringret=s;returnret;}

c++基礎(chǔ)教案2.3內(nèi)聯(lián)函數(shù)在程序執(zhí)行函數(shù)調(diào)用時,要求在轉(zhuǎn)去前要保護(hù)現(xiàn)場保存地址,轉(zhuǎn)回后先要恢復(fù)現(xiàn)場,并按原來保存地址繼續(xù)執(zhí)行。因此,函數(shù)調(diào)用要有一定的時間和空間開銷,影響其效率。特別是對于一些函數(shù)體代碼不是很大,但又頻繁地被調(diào)用的函數(shù)來講,解決其效率問題更為重要。因此引入內(nèi)聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)的定義方法

定義內(nèi)聯(lián)函數(shù)的方法很簡單,只要在函數(shù)定義的頭前加上關(guān)鍵字inline即可。c++基礎(chǔ)教案inline

isNumber(charch);//函數(shù)原型聲明inline即內(nèi)聯(lián)函數(shù)void

main()

{

charch;cin.get(ch);if(isNumber(ch))cout<"是數(shù)字字符"<<endl;elsecout<<"不是數(shù)字字符"<<endl;}isNumber(charch);//這里不用再次inline,加上inline也不會出錯的

{

return

(ch>='0'&&ch<='9')?1:0;}

使用inline修飾帶來的好處就是在每個調(diào)用isNumber(ch)的地方都換成了(ch>='0’&&ch<=’9’)?1:0.該函數(shù)在編譯時被替代

,這樣就避免了頻繁調(diào)用函數(shù)對棧內(nèi)存重復(fù)開辟所帶來的消耗。但是會增加目標(biāo)程序代碼量,進(jìn)而增加空間開銷,可見它是以空間換取時間。

c++基礎(chǔ)教案說明:(1)定義內(nèi)聯(lián)函數(shù)只是一種請求,而不是命令編譯器一定這么做(2)內(nèi)聯(lián)函數(shù)應(yīng)該在頭文件中定義(3)inline只適合函數(shù)體內(nèi)代碼簡單的函數(shù)使用,不能包含復(fù)雜的結(jié)構(gòu)控制語句例如while、switch,并且內(nèi)聯(lián)函數(shù)本身不能直接調(diào)用遞歸函數(shù)(自己內(nèi)部還調(diào)用自己的函數(shù))。c++基礎(chǔ)教案2.4函數(shù)重載重載可分為函數(shù)重載和運算符重載函數(shù)重載在C++程序中,可以將語義、功能相似的幾個函數(shù)用同一個名字表示,即函數(shù)重載。這樣便于記憶,提高了函數(shù)的易用性。例如函數(shù)EatBeef,EatFish,EatChicken可以用同一個函數(shù)名Eat表示,用不同類型的參數(shù)加以區(qū)別。voidEatBeef(…);//可以改為

voidEat(Beef…);voidEatFish(…);//可以改為

voidEat(Fish…);voidEatChicken(…);//改為

voidEat(Chicken…);c++基礎(chǔ)教案例如:intsum(inta,intb){}doublesum(doublea,doubleb){}

調(diào)用重載函數(shù)時,編譯器會根據(jù)實參的類型、個數(shù)、順序去調(diào)用相應(yīng)的函數(shù)。

intsum1=sum(5,6);doublesum2=sum(3.4,5.6);注:僅僅返回類型不同是不行的c++基礎(chǔ)教案第三節(jié)類和對象類的定義和實現(xiàn)類的靜態(tài)成員類的對象的定義和使用類的成員函數(shù)構(gòu)造函數(shù)與析構(gòu)函數(shù)c++基礎(chǔ)教案第三節(jié)類和對象類是一種復(fù)雜的數(shù)據(jù)類型,它是將不同類型的數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的操作封裝在一起的集合體。這有點像C語言中的結(jié)構(gòu),唯一不同的就是結(jié)構(gòu)沒有定義所說的“數(shù)據(jù)相關(guān)的操作”,即“方法”

封裝外部用戶只能看到定義抽象行為的操作集合程序員通過數(shù)據(jù)變量維護(hù)對象內(nèi)部的狀態(tài)c++基礎(chǔ)教案3.1類的定義和實現(xiàn)類的定義一般地分為說明部分和實現(xiàn)部分。

說明部分是用來說明該類中的成員,包含數(shù)據(jù)成員的說明和成員函數(shù)的說明?!案墒裁础?/p>

實現(xiàn)部分是用來對成員函數(shù)的定義。“怎么干”。類的一般定義格式如下:class類名//class是定義類的關(guān)鍵字,<類名>是種標(biāo)識符,通常用字母C開頭{

public:

公有成員函數(shù)或數(shù)據(jù)成員的說明

private:

私有數(shù)據(jù)成員或成員函數(shù)的說明

};

//注意:分號不可缺c++基礎(chǔ)教案類的定義訪問權(quán)限修飾符或訪問控制修飾符:公有的(public)、私有的(private)和保護(hù)的(protected)public:公有部分往往是一些操作(成員函數(shù)),它是提供給用戶的接口功能。這部分成員不僅可以在類內(nèi)被訪問,也可以在類外被訪問。private:私有部分通常是一些數(shù)據(jù)成員,描述該類中的對象的屬性,用戶是無法訪問它們的,只有成員函數(shù)或經(jīng)特殊說明的函數(shù)才可以引用它們,它們是被用來隱藏的部分。protected:可以被本類及其繼承類使用c++基礎(chǔ)教案一個日期類定義的例子//類的說明部分,一般放在date.h文件中classCdate

{public:

voidsetDate(inty,intm,intd);

intIsLeapYear();

voidPrint();

private:

intyear,month,day;

};//類的實現(xiàn)部分一般放在date.cpp文件中#include“date.h”voidCdate::setDate(inty,intm,intd)這里出現(xiàn)的作用域運算符::{year=y;month=m;day=d;}是用來標(biāo)識某個成員函數(shù)是屬于哪

intCdate::IsLeapYear()個類,如果成員函數(shù)定義在類體外{要使用作用域運算符::return(year%4==0&&year%100!=0)||(year%400==0);}voidCdate::Print();

{

cout<<year<<montb<<day<<endl;}c++基礎(chǔ)教案類的定義說明

定義類時應(yīng)注意的事項1)在類體中不允許對所定義的數(shù)據(jù)成員進(jìn)行初始化。2)一般地,在類體內(nèi)先說明公有成員,它們是用戶所關(guān)心的,后說明私有成員,它們是用戶不感興趣的。在說明數(shù)據(jù)成員時,一般按數(shù)據(jù)成員的類型大小,由小至大說明,這樣可提高時空利用率。3)習(xí)慣地將類定義的說明部分放在頭文件中.h。而實現(xiàn)部分放在.cpp文件中c++基礎(chǔ)教案3.1.2類的實現(xiàn)類成員函數(shù)的實現(xiàn)部分一般放在.cpp文件中,如果要在類外使用類中的實例變量或者在類外定義函數(shù)體,要使用作用域運算符,用來標(biāo)識某個成員是屬于哪個類的。格式返回值類型類名::函數(shù)名(參數(shù)列表)

{……}例如:voidCdate::setDate(inty,intm,intd)

{

year=y;

month=m;

day=d;

}c++基礎(chǔ)教案作用域運算符classPlayingCard{public:enumSuits{Spade,Diamond,Club,Heart};Suitssuit(){returnsuitValue;}intrank(){returnrankValue;}private:SuitssuitValue;intrankValue;booleanfaceUp;};如:在類定義之外使用表示花色的常量

if(aCard.suit()==PlayingCard::Diamond)……c++基礎(chǔ)教案3.2類的靜態(tài)成員被一個類的所有實例共享的公共數(shù)據(jù)成員。靜態(tài)成員(static)可以實現(xiàn)同一個類的多個對象之間的數(shù)據(jù)共享。靜態(tài)數(shù)據(jù)成員對于類的所有對象只開辟了一塊內(nèi)存空間(在靜態(tài)存儲區(qū)),其中一個對象對其改變,保證所有對象存取的是更新后的相同的值。靜態(tài)數(shù)據(jù)成員的使用方法和注意事項如下:

1、定義:靜態(tài)數(shù)據(jù)成員在定義或說明時前面加關(guān)鍵字static。

2、初始化:格式如下:

<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<值>:初始化在類體外進(jìn)行,前面不加static和訪問權(quán)限控制符private,public等。初始化時使用作用域運算符來標(biāo)明它所屬類,因為靜態(tài)數(shù)據(jù)成員是類的成員,而不是對象的成員。靜態(tài)數(shù)據(jù)成員是靜態(tài)存儲的,必須對它進(jìn)行初始化。

3、引用

<類名>::<靜態(tài)成員名>c++基礎(chǔ)教案classMyclass

{

public:

Myclass(inta,intb,intc);

voidGetNumber();

voidGetSum();

private:

intA,B,C;

staticintSum;

};實現(xiàn)

intMyclass::Sum=0;

Myclass::Myclass(inta,intb,intc)

{

A=a;

B=b;

C=c;

Sum+=A+B+C;

}調(diào)用

MyclassM(3,7,10),N(14,9,11);

c++基礎(chǔ)教案3.3類的對象的定義和使用對象的定義有兩種方法class類名

{

……

}對象名;2.也可以先聲明類,然后定義類的對象類名對象名;編譯系統(tǒng)為對象分配內(nèi)存并且將這段內(nèi)存空間與對象名稱進(jìn)行綁定,并進(jìn)行必要的初始化操作.變量聲明只是創(chuàng)建了一個標(biāo)識變量的名稱,大部分面向?qū)ο笳Z言通過new操作符來創(chuàng)建對象,c++語言可以將他們結(jié)合起來如PlayingCardaCard;//在java中必須寫成PlayingCardaCard=newPlayingCard();c++基礎(chǔ)教案使用對象:在調(diào)用成員函數(shù)時,必須指明對類的哪個對象進(jìn)行操作。利用成員運算符.表明從屬關(guān)系,用于類的對象例如:Cdatedate,*p;date.setDate(2007,7,20);p=&date;p->IsLeapYear();//等價于date.IsLeapYear();c++基礎(chǔ)教案3.4類的成員函數(shù)成員函數(shù)的定義和聲明:類的所有成員必須在類定義的{}內(nèi)聲明。類的成員函數(shù)既可以在類內(nèi)定義,以可以在類外定義,他可以訪問該類的private成員如:boolsame_isbn(constSalesItem&r)const{returnisbn==r.isbn;}沒有前綴的isbn指的是用于調(diào)用函數(shù)的對象的isbn調(diào)用調(diào)用函數(shù)時,實際是使用對象來調(diào)用的if(total.same_isbn(trans))……//r是trans的引用c++基礎(chǔ)教案this指針每個成員函數(shù)都有一個額外的、隱含的形參將該成員函數(shù)與調(diào)用該函數(shù)的類對象綁定在一起,這個形參為this。調(diào)用成員函數(shù)時,形參this初始化為調(diào)用函數(shù)的對象的地址。所以total.same_isbn(trans)可以理解為same_isbn(&total,trans)//第一個參數(shù)為隱含的,它傳遞的是調(diào)用對象的地址使用this

在函數(shù)體中可以顯式地使用

boolsame_isbn(constSalesItem&r)const{returnthis->isbn==r.isbn;}c++基礎(chǔ)教案當(dāng)成員函數(shù)中函數(shù)參數(shù)與數(shù)據(jù)成員同名時,需要this指針

classPlayingCard{PlayingCard(intsuit,intrank){this->rank=rank;this->suit=suit;this->faceUp=true;}c++基礎(chǔ)教案const成員函數(shù)使用const關(guān)鍵字進(jìn)行說明的成員函數(shù)為常成員函數(shù)。只有常成員函數(shù)才有資格操作常量或常對象,沒有使用const關(guān)鍵字說明的成員函數(shù)不能用來操作常對象。說明格式如下:

類型說明符

函數(shù)名

(參數(shù)表)const;

其中,const是加在函數(shù)說明后面的類型修飾符,它是函數(shù)類型的一個組成部分,因此,在函數(shù)實現(xiàn)部分也要帶const關(guān)鍵字。任何不會修改數(shù)據(jù)成員的函數(shù)都應(yīng)該聲明為const類型。如果在編寫const成員函數(shù)時,不慎修改了數(shù)據(jù)成員,或者調(diào)用了其它非const成員函數(shù),編譯器將指出錯誤,這無疑會提高程序的健壯性。

c++基礎(chǔ)教案classStack{public:voidPush(intelem);intPop(void);intGetCount(void)const;//const成員函數(shù)private:intm_num;intm_data[100];};intStack::GetCount(void)const{

++m_num;//編譯錯誤,企圖修改數(shù)據(jù)成員m_numPop();//編譯錯誤,企圖調(diào)用非const函數(shù)returnm_num;}c++基礎(chǔ)教案3.5構(gòu)造函數(shù)與析構(gòu)函數(shù)概述構(gòu)造函數(shù)的初始化表缺省的構(gòu)造函數(shù)缺省的拷貝構(gòu)造函數(shù)運算符重載缺省的賦值函數(shù)析構(gòu)函數(shù)c++基礎(chǔ)教案3.5.1概述每個類只有一個析構(gòu)函數(shù)和一個賦值函數(shù),但可以有多個構(gòu)造函數(shù)(包含一個拷貝構(gòu)造函數(shù),其它的稱為普通構(gòu)造函數(shù))。對于任意一個類A,如果不想編寫上述函數(shù),C++編譯器將自動為A產(chǎn)生四個缺省的函數(shù),如A();//缺省的無參數(shù)構(gòu)造函數(shù)A(constA&a);//缺省的拷貝構(gòu)造函數(shù)~A();//缺省的析構(gòu)函數(shù)A&operate=(constA&a);//缺省的賦值函數(shù)c++基礎(chǔ)教案作用:把對象的初始化工作放在構(gòu)造函數(shù)中,把清除工作放在析構(gòu)函數(shù)中。當(dāng)對象被創(chuàng)建時,構(gòu)造函數(shù)被自動執(zhí)行。當(dāng)對象消亡時,析構(gòu)函數(shù)被自動執(zhí)行。這樣可以自動執(zhí)行對象的初始化和清除工作。命名:構(gòu)造函數(shù)、析構(gòu)函數(shù)與類同名,由于析構(gòu)函數(shù)的目的與構(gòu)造函數(shù)的相反,就加前綴‘~’以示區(qū)別。構(gòu)造、析構(gòu)函數(shù)沒有返回值,即使是void也不可以。構(gòu)造、析構(gòu)函數(shù)置于類定義的public部分析構(gòu)函數(shù)不得帶有任何參數(shù)構(gòu)造函數(shù)可以有一個或多個,一旦定義一個有參的構(gòu)造函數(shù),一定要顯式定義一個無參構(gòu)造函數(shù)c++基礎(chǔ)教案3.5.2構(gòu)造函數(shù)的初始化表和其他函數(shù)不同,構(gòu)造函數(shù)有個特殊的初始化方式叫“初始化表達(dá)式表”(初始化表)。初始化表位于函數(shù)參數(shù)表之后,以冒號開始,后面接數(shù)據(jù)成員列表,列表之間用逗號分隔,每一個變量后面用一對圓括號包含它的初始值

。初始化表放在構(gòu)造函數(shù)的定義中PlayingCard::PlayingCard(Suitsis,intir)

:suit(is),rank(ir),faceUp(true){//函數(shù)體

}c++基礎(chǔ)教案(2)執(zhí)行順序首先執(zhí)行初始化列表,然后執(zhí)行該構(gòu)造函數(shù)函數(shù)體中的語句成員對象初始化的次序完全不受它們在初始化表中次序的影響,只由成員對象在類中聲明的次序決定。這是因為類的聲明是唯一的,而類的構(gòu)造函數(shù)可以有多個,因此會有多個不同次序的初始化表。如果成員對象按照初始化表的次序進(jìn)行構(gòu)造,這將導(dǎo)致析構(gòu)函數(shù)無法得到唯一的逆序。例

classx{inti;intj;public:x(intval):j(val),i(j){}//相當(dāng)于i=j;j=val;j還沒有初值就被使用

};

所以盡量避免使用成員來初始化其他成員

x(intval):j(val),i(val){}c++基礎(chǔ)教案const數(shù)據(jù)成員const數(shù)據(jù)成員只在某個對象生存期內(nèi)是常量,而對于整個類而言卻是可變的,因為類可以創(chuàng)建多個對象,不同的對象其const數(shù)據(jù)成員的值可以不同。

不能在類聲明中初始化const數(shù)據(jù)成員。以下用法是錯誤的,因為類的對象未被創(chuàng)建時,編譯器不知道SIZE的值是什么。

classA

{…

constintSIZE=100;

//錯誤,企圖在類聲明中初始化const數(shù)據(jù)成員

intarray[SIZE];

//錯誤,未知的SIZE

};

const數(shù)據(jù)成員的初始化只能在類構(gòu)造函數(shù)的初始化表中進(jìn)行,

類的定義

classA

{…

A(intsize);

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

constintSIZE;

};

類的實現(xiàn)

A::A(intsize):SIZE(size)

//構(gòu)造函數(shù)的初始化表

{…}生成類的對象

A

a(100);

//對象a的SIZE值為100

A

b(200);

//對象b的SIZE值為200c++基礎(chǔ)教案(3)使用說明大多數(shù)成員可以在構(gòu)造函數(shù)的初始化表中初始化,也可以在函數(shù)體中賦值。但是類的const常量和引用成員只能在初始化表里被初始化,因為不能對他們賦值,所以要在執(zhí)行構(gòu)造函數(shù)的函數(shù)體之前完成初始化。classConstRef{public:ConstRef(intii);private:inti;constintci;int&ri;};c++基礎(chǔ)教案ConstRef::ConstRef(intii){i=ii;ci=ii;//不能對常量賦值

ri=i;//此時是對ri所綁定的對象賦值,但是還不知道ri是誰的別名}ConstRef::ConstRef(intii):i(ii),ci(ii),ri(i){}c++基礎(chǔ)教案3.5.3缺省的構(gòu)造函數(shù)格式:A::A(){}當(dāng)類沒有定義構(gòu)造函數(shù)時,編譯器才會自動生成一個不帶參數(shù)的缺省構(gòu)造函數(shù)在缺省構(gòu)造函數(shù)中,對于類中的成員,若為類類型,調(diào)用默認(rèn)構(gòu)造函數(shù)來初始化;若為內(nèi)置或復(fù)合類型(指針、數(shù)組),若對象定義在局部作用域中,必須對它賦初值使用缺省構(gòu)造函數(shù)創(chuàng)建對象

Complexc;

注:Complexc();是錯誤的。編譯器把他解釋為一個函數(shù)的聲明。c是函數(shù)名,返回類型為Complex一旦定義一個有參的構(gòu)造函數(shù),一定要顯式的定義一個無參構(gòu)造函數(shù)c++基礎(chǔ)教案Complex::Complex(doubler,doublei){real=r;image=i;}Complex::Complex(doubler){real=r;image=0;}Complex::Complex(){real=0;image=0;cout<<

“Initializing00”<<endl;}調(diào)用方式:創(chuàng)建對象時自動調(diào)用缺省的構(gòu)造函數(shù)Complexc1;

Complex*pc1=newComplex;//注意,調(diào)用缺省構(gòu)造函數(shù)時,沒有括號調(diào)用有參構(gòu)造函數(shù)Complexc2(4.5);

或Complexc2=newComplex(4.5);//一個參數(shù)Complexc3(4.5,6.2);

Complexc3=newComplex(4.5,6.2);c++基礎(chǔ)教案3.5.4缺省的拷貝(復(fù)制)構(gòu)造函數(shù)格式:A(constA&a)

他只有一個參數(shù),且是所在類的對象的引用作用:利用編譯器提供的拷貝構(gòu)造函數(shù)創(chuàng)建新的對象,將形參對象中的成員逐個的拷貝到新的對象中。即新對象初始化為原對象的副本

Cpoint::Cpoint(constCpoint&obj){x=obj.x;y=obj.y;}若已經(jīng)定義并初始化了Cpoint對象c1,則可以定義Cpointc2=c1;相當(dāng)于調(diào)用c2.Cpoint(c1);c++基礎(chǔ)教案在類中,初始化對象有兩種方式直接初始化:用括弧直接調(diào)用與實參匹配的構(gòu)造函數(shù)。如:stringdots(10,'.');stringempty;復(fù)制初始化:用等號首先使用指定構(gòu)造函數(shù)創(chuàng)建一個臨時對象,然后使用復(fù)制構(gòu)造函數(shù)將那個臨時對象復(fù)制到正在創(chuàng)建的對象。stringempty_copy=string();復(fù)制構(gòu)造函數(shù)的應(yīng)用場合定義一個對象并用一個同類型對象初始化時類的對象作為實參傳遞給形參時從函數(shù)返回時復(fù)制一個對象即使是定義了其他的構(gòu)造函數(shù),這個缺省的復(fù)制構(gòu)造函數(shù)也是存在的c++基礎(chǔ)教案3.5.5運算符重載對于基本數(shù)據(jù)類型,有許多相應(yīng)的基本運算,如算術(shù)運算的+、-、*、/,但是對用戶自定義類型,卻不可以用這些運算符進(jìn)行運算,為了使類類型也能使用這些運算符,必須對這些運算符進(jìn)行重載重載操作符是具有特殊名稱的函數(shù),在C++語言中,可以用關(guān)鍵字operator加上運算符來表示函數(shù)名,叫做運算符重載。遵循的規(guī)則:**不能改變原運算符操作數(shù)的個數(shù)

+++**不能改變原運算符的自然含義

**重載操作符必須具有至少一個類類型或枚舉類型的操作數(shù),既不能對內(nèi)置類型對象的操作符重載。不能重載的運算符:成員運算符.

作用域運算符::

條件運算符?:一元運算符*c++基礎(chǔ)教案

如果運算符被重載為類的成員函數(shù),那么一元運算符沒有參數(shù),二元運算符只有一個參數(shù),因為對象自己成了左側(cè)參數(shù)。從語法上講,運算符既可以定義為友元函數(shù),也可以定義為成員函數(shù)。作為類的成員函數(shù)重載的格式:一元運算符返回值類型

類名::operator運算符()

//operator運算符作為一個整體作為函數(shù)名

{……}二元運算符返回值類型

類名::operator運算符(參數(shù)說明)

{……}//參數(shù)說明只允許有一個參數(shù),即右操作數(shù)c++基礎(chǔ)教案例如:對復(fù)數(shù)進(jìn)行相加,通過+號能直接實現(xiàn)類內(nèi)聲明:

Complexoperator+(constComplex&a);類外定義:

ComplexComplex::operator+(constComplex&a){Complextemp(real+a.real,image+a.image);returntemp;}使用重載操作符:與內(nèi)置類型使用操作符的方式一樣intmain(){Complexc1(1.0,1.0),C2(2.0,2.0),C;C=C1+C2;//C++編譯器把他解釋為C=C1.operator+(c2);}c++基礎(chǔ)教案3.5.6缺省的賦值函數(shù)格式:A&operator=(constA&a)為成員函數(shù),包含隱式的this形參,第一個形參為對應(yīng)的左操作數(shù),第二個形參為對應(yīng)的右操作數(shù),右操作數(shù)一般為const引用傳遞。返回值為左操作數(shù)的引用通過重載=,可以對對象整體賦值缺省的賦值函數(shù):

右操作數(shù)對象的每個成員賦值給左操作數(shù)對象的每個成員,返回左操作數(shù)對象的引用Complex&Complex::operator=(constComplex&a){real=a.real;image=a.image;return*this;}c++基礎(chǔ)教案拷貝構(gòu)造函數(shù)與賦值函數(shù)的比較拷貝構(gòu)造函數(shù)和賦值函數(shù)非常容易混淆,常導(dǎo)致錯寫、錯用??截悩?gòu)造函數(shù)是在對象被創(chuàng)建時調(diào)用的,而賦值函數(shù)只能被已經(jīng)存在了的對象調(diào)用。Stringa(“hello”);Stringb(“world”);Stringc=a;//調(diào)用了拷貝構(gòu)造函數(shù),最好寫成c(a);c=b;//調(diào)用了賦值函數(shù)c++基礎(chǔ)教案賦值和復(fù)制

內(nèi)存分配方法影響賦值的含義:

1.復(fù)制語義:c++中使用,實際是調(diào)用的賦值函數(shù),右側(cè)變量值賦給左側(cè)變量,兩個變量占用不同存儲空間,值是獨立的

2.指針語義:同一(Java中使用)左側(cè)變量的地址賦給了右側(cè)變量的地址,兩個變量是共用同一地址,其中一個變量值的改變會改變另一個變量c++基礎(chǔ)教案3.5.8析構(gòu)函數(shù)在對象脫離其作用域時,系統(tǒng)自動執(zhí)行析構(gòu)函數(shù),作善后清理工作,主要用于資源回收析構(gòu)函數(shù)與類同名,無參數(shù),無返回值。只是在函數(shù)名前加~

例:Complex::~Complex(){}編譯器總會自動生成一個析構(gòu)函數(shù),他按成員在類中的聲明次序逆序撤銷成員。默認(rèn)析構(gòu)函數(shù)釋放對象生命期內(nèi)或構(gòu)造函數(shù)中獲取的資源。注:動態(tài)分配的對象只有在指向該對象的指針被刪除時才會撤銷,若沒有刪除,不會運行該對象的析構(gòu)函數(shù),對象一直存在,會導(dǎo)致內(nèi)存泄漏當(dāng)對象的引用或指針超出作用域時,不會運行析構(gòu)函數(shù)。當(dāng)刪除指向動態(tài)分配對象的指針或?qū)嶋H對象超出作用域時,才會運行析構(gòu)函數(shù)c++基礎(chǔ)教案第四節(jié)友元和重載友元友元函數(shù)友元類友元關(guān)系與繼承重載與友元重載重載輸出運算符重載輸入運算符轉(zhuǎn)換與類類型c++基礎(chǔ)教案4.1友元我們已知道類具有封裝和信息隱藏的特性。只有類的成員函數(shù)才能訪問類的私有成員。非成員函數(shù)可以訪問類中的公有成員,但是如果將數(shù)據(jù)成員都定義為公有的,這又破壞了隱藏的特性。另外,應(yīng)該看到在某些情況下,特別是在對某些成員函數(shù)多次調(diào)用時,由于參數(shù)傳遞,類型檢查和安全性檢查等都需要時間開銷,而影響程序的運行效率。為了解決上述問題,提出一種使用友元的方案。友元是一種定義在類外部的普通函數(shù),但它需要在類體內(nèi)進(jìn)行說明,為了與該類的成員函數(shù)加以區(qū)別,在說明時前面加以關(guān)鍵字friend。友元不是成員函數(shù),但是它可以訪問類中的私有成員。友元的作用在于提高程序的運行效率,但是,它破壞了類的封裝性和隱藏性,使得非成員函數(shù)可以訪問類的私有成員。

c++基礎(chǔ)教案4.1.1友元函數(shù)友元可以是一個函數(shù),該函數(shù)被稱為友元函數(shù);友元也可以是一個類,該類被稱為友元類。

1、友元函數(shù)

友元函數(shù)的特點是他是能夠訪問類中的私有成員的非成員函數(shù)。友元函數(shù)從語法上看,它與普通函數(shù)一樣,即在定義上和調(diào)用上與普通函數(shù)一樣。下面舉一例子說明友元函數(shù)的應(yīng)用。

c++基礎(chǔ)教案#include

<iostream>

usingnamespacestd;

class

Point

{

public:

Point(double

xx,

double

yy)

{

x=xx;

y=yy;

}

void

Getxy();

friend

double

Distance(Point

&a,

Point

&b);

//不是Point的成員函數(shù)而是友元函數(shù),他不受類的訪問控制的影響

private:

double

x,

y;

};

void

Point::Getxy()

{cout<<"("<<x<<","<<y<<")"<<endl;

}

double

Distance(Point

&a,

Point

&b)

{

double

dx

=

a.x

-

b.x;//可以調(diào)用類的私有成員

double

dy

=

a.y

-

b.y;

return

sqrt(dx*dx+dy*dy);

}c++基礎(chǔ)教案void

main()

{

Point

p1(3.0,

4.0),

p2(6.0,

8.0);

p1.Getxy();

p2.Getxy();

double

d

=

Distance(p1,

p2);

//友元函數(shù)被調(diào)用時與普通函數(shù)一樣

cout<<"Distance

is"<<d<<endl;}說明:類中說明了一個友元函數(shù)Distance(),說明時加friend關(guān)鍵字,標(biāo)識它不是成員函數(shù),而是友元函數(shù)。定義方法與普通函數(shù)定義一樣,而不同于成員函數(shù)的定義,因為它不需要指出所屬的類。但是它可以引用類中的私有成員調(diào)用友元函數(shù),也是同普通函數(shù)的調(diào)用一樣,不要像成員函數(shù)那樣調(diào)用。c++基礎(chǔ)教案4.1.2友元類友元還可以是類,即一個類可以作另一個類的友元。當(dāng)一個類作為另一個類的友元時,這就意味著這個類的所有成員函數(shù)都是另一個類的友元函數(shù)。

classBase{friendclassFrnd;//聲明Frnd為Base的友元類·protected:inti;};classFrnd{public:intmem(Baseb){returnb.i;}//Frnd中可以訪問Base的私有變量

intmem(D1d){returnd.i;}×};c++基礎(chǔ)教案4.1.3友元關(guān)系與繼承友元關(guān)系不能繼承?;惖挠言獙ε缮惖某蓡T沒有特殊的訪問權(quán)限。同樣,如果某一基類具有特殊的訪問權(quán)限,該基類的派生類不能訪問授予友元關(guān)系的類classD1:publicBase{protected:intj;};classD2:publicFrnd{public:intmem(Baseb)({returnb.i;}c++基礎(chǔ)教案4.1.3重載與友元兩個復(fù)數(shù)類型相加,可以定義重載函數(shù)為Complex的成員函數(shù)。但是,如果+前的操作數(shù)不是Complex類型,我們可以采用友元函數(shù)解決這個問題類內(nèi)聲明:

friendComplexoperator+(doubled,constComplex&a);//注:友元不是成員函數(shù),在類外定義時也不再加friend

類外定義:

Complexoperator+(doubled,constComplex&a){Complextemp(d+a.real,a.image);returntemp;}運算符規(guī)則

所有的一元運算符建議重載為成員函數(shù)

=()[]->只能重載為成員函數(shù)

二元操作符+=-=/=*=&=|=~=%=>=<=建議重載為類成員函數(shù)

所有其它運算符建議重載為友元函數(shù)c++基礎(chǔ)教案4.2重載與輸入輸出操作符支持I/O操作的類所提供的I/O操作接口,一般應(yīng)該與標(biāo)準(zhǔn)庫iostream為內(nèi)置類型定義的接口相同。因此,許多類都需要重載輸入輸出操作符輸出流庫中對左移操作符的重載ostream&operator<<(ostream&des,constintsource);ostream&operator<<(ostream&des,constshortsource);ostream&operator<<(ostream&des,constlongsource);ostream&operator<<(ostream&des,constcharsource);ostream&operator<<(ostream&des,constchar*source);c++基礎(chǔ)教案4.2.1輸出操作符的重載ostream&operator<<(ostream&des,constcharsource);為了與i/o標(biāo)準(zhǔn)庫一致,操作符應(yīng)接受ostream&作為第一個形參,該形參是一個引用,因為不能復(fù)制ostream對象對類類型const對象的引用作為第二個形參,這樣避免復(fù)制實參,且輸出一般不會改變對象。返回對ostream形參的引用ostream&operator<<(ostream&os,constClassType&object){os<<……;returnos;}c++基礎(chǔ)教案4.2.1輸出操作符的重載IO操作符必須為非成員函數(shù)如果<<為類的成員,則左操作數(shù)只能是該類的對象。但是,我們的左操作數(shù)必須為ostream類型,ostream類是標(biāo)準(zhǔn)庫的組成部分,我們不能為標(biāo)準(zhǔn)庫的類增加成員。所以,如果想使用該操作符,只能把它定義為非成員函數(shù),且他是某個使用它的類的友元classNode{friendostream&operator<<(ostream&,constNode&);private:intscore;char*name;};ostream&operator<<(ostream&out,constNode&x){out<<x.score<<''<<[0]<<'';returnout;}c++基礎(chǔ)教案4.2.2輸入操作符的重載輸入操作符的第一個形參是引用,只想它要讀入的流,并且返回的也是對同一流的引用。他的第二個形參是要讀入的對象的非const引用。istream&operator>>(istream&in,Node&x){in>>x.score;returnin;}與輸出操作符不同,輸入操作符必須處理讀操作因為提供的值不正確而失敗的錯誤和文件結(jié)束的可能性

if(in)……elsex=Node();c++基礎(chǔ)教案4.2.3轉(zhuǎn)換與類類型classSmallInt{friendoperator+(constSmallInt&,int);

friendoperator-(constSmallInt&,int);friendoperator+(int,constSmallInt&);friendoperator-(int,constSmallInt&);public:SmallInt(intival):value(ival){}operator+(constSmallInt&);operator-(constSmallInt&);private:intvalue;};一個類可以定義自

溫馨提示

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

評論

0/150

提交評論