《C++程序設(shè)計》學(xué)習(xí)筆記總結(jié) - 第三章 類和對象進階_第1頁
《C++程序設(shè)計》學(xué)習(xí)筆記總結(jié) - 第三章 類和對象進階_第2頁
《C++程序設(shè)計》學(xué)習(xí)筆記總結(jié) - 第三章 類和對象進階_第3頁
《C++程序設(shè)計》學(xué)習(xí)筆記總結(jié) - 第三章 類和對象進階_第4頁
《C++程序設(shè)計》學(xué)習(xí)筆記總結(jié) - 第三章 類和對象進階_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第三章類和對象進階一、構(gòu)造函數(shù),創(chuàng)建對象自動調(diào)用對于C++中基本數(shù)據(jù)類型的變量,可以聲明全局變量和函數(shù)內(nèi)部的局部變量1、為了對對象進行初始化,C++提供了一種稱為構(gòu)造函數(shù)的機制,用于對對象進行初始化,實際上是用來為成員變量賦初值的。

2、構(gòu)造函數(shù)是類中的特殊成員函數(shù),它屬于類的一部分。給出類定義時,由程序員編寫構(gòu)造函數(shù)。如果程序員沒有編寫類的任何構(gòu)造函數(shù),則由系統(tǒng)自動添加一個不帶參數(shù)的構(gòu)造函數(shù)。3、聲明對象后,可以使用new運算符為對象進行初始化,此時調(diào)用的是對象所屬類的構(gòu)造函數(shù)。構(gòu)造函數(shù)的作用是完成對象的初始化工作,用來保證對象的初始狀態(tài)是確定的。在對象生成時,系統(tǒng)自動調(diào)用構(gòu)造函數(shù),用戶在程序中不會直接調(diào)用構(gòu)造函數(shù)。定義一個類時,需要為類定義相應(yīng)的構(gòu)造函數(shù)。構(gòu)造函數(shù)的函數(shù)名與類名相同,沒有返回值。一個類的構(gòu)造函數(shù)可以有多個,即構(gòu)造函數(shù)允許重載。同一個類的多個構(gòu)造函數(shù)的參數(shù)表一定不能完全相同。構(gòu)造函數(shù)的聲明格式如下:類名(形參1,形參2,…,形參n);4、在聲明類的構(gòu)造函數(shù)時可以同時給出函數(shù)體,這樣的構(gòu)造函數(shù)稱為內(nèi)聯(lián)函數(shù)。也可以在類體外給出構(gòu)造函數(shù)的定義。構(gòu)造函數(shù)的聲明中,形參的個數(shù)可以為0,即參數(shù)表為空。5、當(dāng)類中沒有定義任何構(gòu)造函數(shù)時,系統(tǒng)會自動添加一個參數(shù)表為空、函數(shù)體也為空的構(gòu)造函數(shù),稱為默認構(gòu)造函數(shù)。所以任何類都可以保證至少有一個構(gòu)造函數(shù)。6、如果程序員在程序中已經(jīng)定義了構(gòu)造函數(shù),則系統(tǒng)不會再添加默認構(gòu)造函數(shù)假設(shè)類的成員變量是x1,x2,…,xn,則在類體外定義構(gòu)造函數(shù)時通常有如下3種形式:形式一:類名::類名(形參1,形參2,…,形參n):x1(形參1),x2(形參2),…,xn(形參n){}

這個是初始化列表的方式,跟第2種是一樣的形式二:類名::類名(形參1,形參2,…,形參n)

{x1=形參1;x2=形參2;……xn=形參n;}形式三:類名::類名(){x1=初始化表達式1;x2=初始化表達式2;……xn=初始化表達式n;}例如,程序2-1中為類myDate定義了兩個構(gòu)造函數(shù),分別如下:myDate::myDate(){

year=1970;

month=1;

day=1;}myDate::myDate(inty,intm,intd){

year=y;

month=m;

day=d;}例3-1構(gòu)造函數(shù)的定義myDate::myDate():year(1970),month(1),day(1){}或是myDate::myDate(inty,intm,intd):year(y),month(m),day(d){}第一個是使用固定值在初始化列表中為各成員變量賦初值,第二個是使用帶入的參數(shù)值通過初始化列表為各成員變量賦初值。構(gòu)造函數(shù)也可以在類體外定義。假定類myDate中已經(jīng)聲明了下列4個構(gòu)造函數(shù):myDate();//不帶參數(shù)myDate(int);//帶1個參數(shù)myDate(int,int);//帶2個參數(shù)myDate(int,int,int);//帶3個參數(shù)則類體外,構(gòu)造函數(shù)的定義如例3-2所示。例3-2在類體外定義構(gòu)造函數(shù)myDate::myDate():year(1970),month(1),day(25){}//不帶參數(shù)myDate::myDate(intd):year(1970),month(1)//帶1個參數(shù){day=d;}myDate::myDate(intm,intd):year(1970)//帶2個參數(shù){

month=m;

day=d;}myDate::myDate(inty,intm,intd)//帶3個參數(shù){

year=y;

month=m;

day=d;}構(gòu)造函數(shù)的使用C++語言規(guī)定,創(chuàng)建類的任何對象時都一定會調(diào)用構(gòu)造函數(shù)進行初始化。對象需要占據(jù)內(nèi)存空間,生成對象時,為對象分配的這段內(nèi)存空間的初始化由構(gòu)造函數(shù)完成。(定義對象時,類的構(gòu)造函數(shù)會被自動調(diào)用)特別地,如果程序中聲明了對象數(shù)組,即數(shù)組的每個元素都是一個對象,則一定要為對象所屬的這個類定義一個無參的構(gòu)造函數(shù)。因為數(shù)組中每個元素都需要調(diào)用無參的構(gòu)造函數(shù)進行初始化,所以必須要有一個不帶參數(shù)的構(gòu)造函數(shù)。myDate*pd=newmyDate();

pd->printDate();使用new創(chuàng)建對象時,還可以寫成:myDate*pd=newmyDate;//未加括號如果程序中聲明了對象數(shù)組,即數(shù)組的每個元素都是一個對象,則一定要為對象所屬的這個類定義一個無參的構(gòu)造函數(shù)。因為數(shù)組中每個元素都需要調(diào)用無參的構(gòu)造函數(shù)進行初始化,所以必須要有一個不帶參數(shù)的構(gòu)造函數(shù)。仍以類myDate為例,如聲明了對象數(shù)組A,即myDateA[3];//3個對象,每個對象都是調(diào)用的默認構(gòu)造函數(shù)此時系統(tǒng)要調(diào)用無參的構(gòu)造函數(shù),為數(shù)組A的3個元素進行初始化。也有特例的情況。如果聲明數(shù)組A時同時給各元素賦了初值,例如,有下列語句:myDateA[3]={myDate(1),myDate(10,25),myDate(1980,9,10)};//也可調(diào)不同的構(gòu)造函數(shù)在構(gòu)造函數(shù)中,需要為類中聲明的所有的成員變量賦初值。對于基本數(shù)據(jù)類型的成員變量,如果程序中沒有進行顯式的初始化,則系統(tǒng)使用0進行初始化。復(fù)制構(gòu)造函數(shù)與類型轉(zhuǎn)換構(gòu)造函數(shù)復(fù)制構(gòu)造函數(shù)是構(gòu)造函數(shù)的一種,也稱為拷貝構(gòu)造函數(shù)。它的作用是使用一個已存在的對象去初始化另一個正在創(chuàng)建的對象。例如,類對象間的賦值是由復(fù)制構(gòu)造函數(shù)實現(xiàn)的復(fù)制構(gòu)造函數(shù)只有一個參數(shù),參數(shù)類型是本類的引用。復(fù)制構(gòu)造函數(shù)的參數(shù)可以是const引用,也可以是非const引用。一個類中可以寫兩個復(fù)制構(gòu)造函數(shù),一個函數(shù)的參數(shù)是const引用,另一個函數(shù)的參數(shù)是非const引用。這樣,當(dāng)調(diào)用復(fù)制構(gòu)造函數(shù)時,既能以常量對象(初始化后值不能改變的對象)作為參數(shù),也能以非常量對象作為參數(shù)去初始化其他對象。對于類A而言,復(fù)制構(gòu)造函數(shù)的原型如下(格式一)

A::A(constA&)

Student(constStudent&s);(格式二)

A::A(A&)

Student(Student&s);設(shè)有程序2-1和程序2-2中定義的類myDate和類Student,則主函數(shù)中可以有如下的語句:Studentstud;Studentss[2]={stud,Student()};第二條語句也可以寫為如下的三條語句:Studentss[2];ss[0]=Student(stud);ss[1]=Student();創(chuàng)建數(shù)組ss時,具體來說,是創(chuàng)建ss[0]中的對象時,用到了默認復(fù)制構(gòu)造函數(shù)??梢栽陬愔卸x自己的復(fù)制構(gòu)造函數(shù)。例3-14自定義復(fù)制構(gòu)造函數(shù)在類Student中聲明復(fù)制構(gòu)造函數(shù)的原型:Student(constStudent&s);復(fù)制構(gòu)造函數(shù)的函數(shù)體如下:Student::Student(constStudent&s){name=;birthday=s.birthday;}則在主函數(shù)中調(diào)用自定義的復(fù)制構(gòu)造函數(shù)的語句如下:Studentss[2]={stud,Student()};stud.printStudent()自動調(diào)用復(fù)制構(gòu)造函數(shù)的情況有以下3種:1)當(dāng)用一個對象去初始化本類的另一個對象時,會調(diào)用復(fù)制構(gòu)造函數(shù)。例如,使用下列形式的說明語句時,即會調(diào)用復(fù)制構(gòu)造函數(shù)。類名對象名2(對象名1);類名對象名2=對象名1;2)如果函數(shù)F的參數(shù)是類A的對象,那么當(dāng)調(diào)用F時,會調(diào)用類A的復(fù)制構(gòu)造函數(shù)。換句話說,作為形參的對象,是用復(fù)制構(gòu)造函數(shù)初始化的,而且調(diào)用復(fù)制構(gòu)造函數(shù)時的參數(shù),就是調(diào)用函數(shù)時所給的實參。3)如果函數(shù)的返回值是類A的對象,那么當(dāng)函數(shù)返回時,會調(diào)用類A的復(fù)制構(gòu)造函數(shù)。也就是說,作為函數(shù)返回值的對象是用復(fù)制構(gòu)造函數(shù)初始化的,而調(diào)用復(fù)制構(gòu)造函數(shù)時的實參,就是retrun語句所返回的對象。注意,在復(fù)制構(gòu)造函數(shù)的參數(shù)表中,加上const是更好的做法。這樣復(fù)制構(gòu)造函數(shù)才能接收常量對象作為參數(shù),即才能以常量對象作為參數(shù)去初始化別的對象。真題

構(gòu)造函數(shù)不具備的特征是【D】A.構(gòu)造函數(shù)的函數(shù)名與類名相同B.構(gòu)造函數(shù)可以重載C.構(gòu)造函數(shù)可以設(shè)置默認參數(shù)D.構(gòu)造函數(shù)必須指定返回類型以下選項中,自動調(diào)用類的構(gòu)造函數(shù)的時機是【B】A.定義類的成員函數(shù)時B.定義類的對象時C.定義類的成員對象時D.定義類的友元函數(shù)時聲明一個沒有初始化參數(shù)的對象,需調(diào)用(D)。A:指定參數(shù)構(gòu)造函數(shù)B:拷貝構(gòu)造函數(shù)C:初始化函數(shù)D:默認構(gòu)造函數(shù)AB是一個類,那么執(zhí)行語句ABa(4),b[3],*p;時,調(diào)用的構(gòu)造函數(shù)的次數(shù)是【C】A.2B.3C.4D.5答案:C。【分析】創(chuàng)建對象a時,調(diào)用一次構(gòu)造函數(shù)。創(chuàng)建對象b時,因為這是一個含有3個元素的數(shù)組,所以需要調(diào)用3次構(gòu)造函數(shù)。而對于指針p,僅是說明了這個指針,并未與對象相關(guān),所以并不調(diào)用構(gòu)造函數(shù)。My是一個類,則執(zhí)行語句Mya[3],*p[2];之后,自動調(diào)用構(gòu)造函數(shù)次數(shù)為(B)。注意,這里是定義是長度a【3】=a[0],a[1],a[2]A:2B:3C:4D:5假定一個類的構(gòu)造函數(shù)為A(intaa,intbb){a=aa++;b=a*++bb;},則執(zhí)行Ax(4,5);語句后,x.a和x.b的值分別為(C)。A:4和5B:4和20C:4和24D:20和5以下選項中,自動調(diào)用類的構(gòu)造函數(shù)的時機是(B)。A:定義類的成員函數(shù)時B:定義類的對象時C:定義類的成員對象時D:定義類的友元函數(shù)時假定一個類的構(gòu)造函數(shù)如下:A(intk=4,intj=0){

a=k;

b=j;}則執(zhí)行“Ax(1);”語句后,x.a和x.b的值分別是(A)A:1和0B:1和4C:4和0D:4和1下列說法中,有關(guān)構(gòu)造函數(shù)是正確的是(A)。A:任何一個類必定有構(gòu)造函數(shù)B:可定義沒有構(gòu)造函數(shù)的類C:構(gòu)造函數(shù)不能重載D:任何一類必定有缺省的構(gòu)造函數(shù)

注意:如果類定義了自己的構(gòu)造函數(shù),那么系統(tǒng)默認的無參構(gòu)造函數(shù)就沒有了對于拷貝構(gòu)造函數(shù)和賦值操作的關(guān)系,正確的描述是(C)。A:拷貝構(gòu)造函數(shù)和賦值操作是完全一樣的操作B:進行賦值操作時,不會調(diào)用類的構(gòu)造函數(shù)

如果是Persons1=s2;也是調(diào)復(fù)制構(gòu)造函數(shù)的C:當(dāng)調(diào)用拷貝構(gòu)造函數(shù)時,類的對象正在被建立并被初始化D:拷貝構(gòu)造函數(shù)和賦值操作不能在同一個類中被同時定義類構(gòu)造函數(shù)定義的位置是(A)。A:類體內(nèi)或體外B:只是在類體內(nèi)C:只在類體外D:在類的成員函數(shù)中二、析構(gòu)函數(shù),銷毀對象自動調(diào)用1、與構(gòu)造函數(shù)一樣,析構(gòu)函數(shù)也是成員函數(shù)的一種,它的名字也與類名相同,但要在類名前面加一個“?”字符,以區(qū)別于構(gòu)造函數(shù)。

析構(gòu)函數(shù)沒有參數(shù),也沒有返回值。一個類中有且僅有一個析構(gòu)函數(shù),如果程序中沒有定義析構(gòu)函數(shù),則編譯器自動生成默認的析構(gòu)函數(shù)。

析構(gòu)函數(shù)不可以多于一個,不會有重載的析構(gòu)函數(shù)。默認析構(gòu)函數(shù)的函數(shù)體為空。2、創(chuàng)建對象時自動調(diào)用構(gòu)造函數(shù),那么,什么時候調(diào)用析構(gòu)函數(shù)呢?可想而知,在對象消亡時自動調(diào)用析構(gòu)函數(shù)。析構(gòu)函數(shù)的作用是做一些善后處理的工作。

例如,如果在創(chuàng)建對象時使用new運算符動態(tài)分配了內(nèi)存空間,則在析構(gòu)函數(shù)中應(yīng)該使用delete釋放掉這部分占用的空間,保證空間可再利用當(dāng)使用new運算符生成對象指針時,自動調(diào)用本類的構(gòu)造函數(shù)。使用delete刪除這個對象時,首先為這個動態(tài)對象調(diào)用本類的析構(gòu)函數(shù),然后再釋放這個動態(tài)對象占用的內(nèi)存。例18使用delete語句現(xiàn)在修改類myDate和類Student的無參構(gòu)造函數(shù)和析構(gòu)函數(shù)如下:myDate::myDate():year(1970),month(1),day(10){cout<<”myDate構(gòu)造函數(shù)"<<endl;}myDate::~myDate(){cout<<"myDate析構(gòu)函數(shù)"<<endl;}Student::Student():name("Noname"),birthday(myDate()){cout<<"Student構(gòu)造函數(shù)"<<endl;}Student::~Student(){cout<<"Stuclent析構(gòu)函數(shù)"<<endl;}如果主函數(shù)中執(zhí)行以下語句:Student*stud=newStudent();deletestud;則得到的信息如下:myDate構(gòu)造函數(shù)Student構(gòu)造函數(shù)Student析構(gòu)函數(shù)myDate析構(gòu)函數(shù)3.2析構(gòu)函數(shù)對于對象數(shù)組,要為它的每個元素調(diào)用一次構(gòu)造函數(shù)和析構(gòu)函數(shù)。全局對象數(shù)組的析構(gòu)函數(shù)在程序結(jié)束之前被調(diào)用。例3-19對象數(shù)組與delete語句Student*ss=newStudent[2];delete[]ss;表達式newStudent[2]首先分配2個Student類的對象所需的內(nèi)存,然后為這2個對象各調(diào)用一次構(gòu)造函數(shù)。當(dāng)使用delete釋放動態(tài)對象數(shù)組時,通過“[]”告訴編譯器ss是對象數(shù)組,所以也為這2個對象各調(diào)用一次析構(gòu)函數(shù)。執(zhí)行這兩行語句得到的顯示信息如下:myDate構(gòu)造函數(shù)Student構(gòu)造函數(shù)myDate構(gòu)造函數(shù)Student構(gòu)造函數(shù)Student析構(gòu)函數(shù)myDate析構(gòu)函數(shù)Student析構(gòu)函數(shù)myDate析構(gòu)函數(shù)下面的語句創(chuàng)建了對象指針數(shù)組,消亡時,要分別釋放空間。Student*ss[2]={newStudent(),newStudent()};deletess[0];deletess[1];析構(gòu)函數(shù)的調(diào)用執(zhí)行順序與構(gòu)造函數(shù)剛好相反將下列程序補充完整。#include<iostream>usingnamespacestd;classSamp{

public:

voidSetij(inta,intb){

i=a;

j=b;

}

?Samp(){

cout<<"析構(gòu).."<<i<<endl;

}

intGetMuti(){

returni*j;

}

protected:

inti;

intj;};intmain(){

Samp*p;

p=newSamp[5];

if(!p){

cout<<"內(nèi)存分配錯誤\n";

return1;

}

for(intj=0;j<5;j++)

p[j].Setij(j,j);

for(intk=0;k<5;k++)

cout<<"Muti["<<k<<"]值是:"<<p[k].GetMuti()<<endl;

delete[]p;

return0;}真題例3-16單項選擇題下面對析構(gòu)函數(shù)的敘述中,正確的是【C】A.系統(tǒng)在任何情況下都能正確析構(gòu)對象

new出來的必需用delete才行,析構(gòu)不行B.用戶必須定義類的析構(gòu)函數(shù)

不定義系統(tǒng)給你默認的C.析構(gòu)函數(shù)沒有參數(shù),也沒有返回值D.析構(gòu)函數(shù)可以設(shè)置默認參數(shù)【分析】通常析構(gòu)函數(shù)用來在對象消亡時析構(gòu)對象。但如果程序中析構(gòu)函數(shù)編寫不正確,或是出現(xiàn)其他問題,則對象不能正確析構(gòu)。選項A是錯誤的。如果程序中沒有定義析構(gòu)函數(shù),則系統(tǒng)會自動添加一個默認析構(gòu)函數(shù)。選項B是錯誤的。析構(gòu)函數(shù)中沒有參數(shù),所以也不可以設(shè)置默認參數(shù)。選項D是錯誤的假定有類AB,有相應(yīng)的構(gòu)造函數(shù)定義,能正確執(zhí)行″ABa(4),b(5),c[3],*p[2]={&a,&b};”語句,請問執(zhí)行完此語句后共調(diào)用該類析構(gòu)函數(shù)的次數(shù)為(B)。A:14B:5C:3D:1使用delete[]刪除對象數(shù)組時,描述正確的是(A)。A:數(shù)組中各元素都調(diào)用析構(gòu)函數(shù)B:數(shù)組中各元素都調(diào)用構(gòu)造函數(shù)C:不調(diào)用析構(gòu)函數(shù)D:只有首元素調(diào)用析構(gòu)函數(shù)析構(gòu)函數(shù)的參數(shù)個數(shù)為(A)。A:0個B:1個C:至少1個D:多于1個定義析構(gòu)函數(shù)時,應(yīng)該注意(C)。A:其名與類名完全相同B:返回類型是void類型C:無形參,也不可重載D:函數(shù)體中必須有delete語句三、類的靜態(tài)成員與C語言一樣,可以使用static說明自動變量。根據(jù)定義的位置不同,分為靜態(tài)全局變量和靜態(tài)局部變量。全局變量是指在所有花括號之外聲明的變量,其作用域范圍是全局可見的,即在整個項目文件內(nèi)都有效。使用static修飾的全局變量是靜態(tài)全局變量,其作用域有所限制,僅在定義該變量的源文件內(nèi)有效,項目中的其他源文件中不能使用它。塊內(nèi)定義的變量是局部變量,從定義之處開始到本塊結(jié)束處為止是局部變量的作用域。使用static修飾的局部變量是靜態(tài)局部變量,即定義在塊中的靜態(tài)變量。靜態(tài)局部變量具有局部作用域,但卻具有全局生存期靜態(tài)局部變量具有局部作用域,但卻具有全局生存期。也就是說,靜態(tài)局部變量在程序的整個運行期間都存在,它占據(jù)的空間一直到程序結(jié)束時才釋放,但僅在定義它的塊中有效,在塊外并不能訪問它靜態(tài)變量均存儲在全局數(shù)據(jù)區(qū),靜態(tài)局部變量只執(zhí)行一次初始化。如果程序未顯式給出初始值,則相當(dāng)于初始化為0;如果顯式給出初始值,則在該靜態(tài)變量所在塊第一次執(zhí)行時完成初始化一定要明白,添加了static后,程序只能賦初始值1次,后面再循環(huán)賦值也不會賦值了,也不會報錯。但是age=age+2;是可以的。靜態(tài)變量只能初始化一次#include<iostream>#include<string>usingnamespacestd;intmain(){

for(inti=0;i<3;i++){

staticintage=5;//這里只會執(zhí)行一次,之后的執(zhí)行可以忽略這行了

age=age+2;

cout<<age<<"";//結(jié)果是:7

9

11

}

}類的靜態(tài)成員類的靜態(tài)成員有兩種:靜態(tài)成員變量和靜態(tài)成員函數(shù)。在類體內(nèi)定義類的成員時,在前面添加static關(guān)鍵字后,該成員即成為靜態(tài)成員類的靜態(tài)成員被類的所有對象共享,不論有多少對象存在,靜態(tài)成員都只有一份保存在公用內(nèi)存中。對于靜態(tài)成員變量,各對象看到的值是一樣的。定義類靜態(tài)成員變量時,在類定義中聲明靜態(tài)成員變量,然后必須在類體外定義靜態(tài)成員變量的初值。這個初值不能在類體內(nèi)賦值。給靜態(tài)成員變量賦初值的格式如下:類型類名::靜態(tài)成員變量=初值;

intPerson::age=25;

注意,在類體外為靜態(tài)成員變量賦初值時,前面不能加static關(guān)鍵字,以免和一般的靜態(tài)變量相混淆。在類體外定義成員函數(shù)時,前面也不能加static關(guān)鍵字。訪問類靜態(tài)成員的一般格式如下

類名::靜態(tài)成員名

對象名.靜態(tài)成員名

對象指針->靜態(tài)成員名類的靜態(tài)成員函數(shù)沒有this指針,不能在靜態(tài)成員函數(shù)內(nèi)訪問非靜態(tài)的成員,即通常情況下,類的靜態(tài)成員函數(shù)只能處理類的靜態(tài)成員變量。靜態(tài)成員函數(shù)內(nèi)也不能調(diào)用非靜態(tài)成員函數(shù)靜態(tài)成員變量的初始化,只能在類體外進行初始化#include<iostream>#include<string>usingnamespacestd;classPerson{

private:

staticintage;//靜態(tài)成員變量

public:

staticintsex;//靜態(tài)成員變量

intgetAge(){

returnage;

}};//靜態(tài)成員變量的初始化,只能在類體外進行初始化intPerson::age=25;//前面不能加static關(guān)鍵字intPerson::sex=1;//前面不能加static關(guān)鍵字intmain(){

Personp1;

cout<<p1.getAge()<<""<<Person::sex;//251}對于普通成員變量,每個對象有各自的一份,而靜態(tài)成員變量只有一份,被同類所有對象共享。普通成員函數(shù)一定是作用在某個對象上的,而靜態(tài)成員函數(shù)并不具體作用在某個對象上。訪問普通成員時,要通過“對象名.成員名”等方式,指明要訪問的成員變量是屬于哪個對象的,或要調(diào)用的成員函數(shù)作用于哪個對象;訪問靜態(tài)成員時,則可以通過“類名::成員名”的方式訪問,不需要指明被訪問的成員屬于哪個對象或作用于哪個對象。因此,甚至可以在還沒有任何對象生成時就訪問一個類的靜態(tài)成員。非靜態(tài)成員的訪問方式其實也適用于靜態(tài)成員,也就是可以通過“對象名.成員名”的方式訪問,效果和“類名::成員名”這種訪問方式?jīng)]有區(qū)別例1:#include<iostream>usingnamespacestd;classTest{

staticintx;//聲明靜態(tài)數(shù)據(jù)成員

intn;

public:

Test(){//定義無參數(shù)的Test類的構(gòu)造函數(shù)

}

Test(inta,intb){//定義含兩個參數(shù)的Test類的構(gòu)造函數(shù)Test為內(nèi)聯(lián)函數(shù)

x=a;

n=b;

}

staticintfunc(){//定義靜態(tài)成員函數(shù)func為內(nèi)聯(lián)函數(shù)

returnx;

}

staticvoidsfunc(Test&r,inta){//定義靜態(tài)成員函數(shù)sfunc為內(nèi)聯(lián)函數(shù),函數(shù)以Test類的引用r和整形數(shù)a為參數(shù)

r.n=a;

}

intGetn(){//定義成員函數(shù)Getn為內(nèi)聯(lián)函數(shù)

returnn;

}};intTest::x=25;//初始化靜態(tài)數(shù)據(jù)成員intmain(){

cout<<Test::func();//x在對象產(chǎn)生之前就存在,輸出"25"

Testb,c;//利用無參數(shù)的構(gòu)造函數(shù)產(chǎn)生Test類的對象b和c

b.sfunc(b,58);//設(shè)置對象b的數(shù)據(jù)成員n,n值為58,r為b的引用

cout<<""<<b.Getn();//輸出"58"

cout<<""<<b.func();//x屬于所有對象,輸出"25"

cout<<""<<c.func();//x屬于所有對象,輸出"25"

Testa(24,56);//利用含兩個參數(shù)的構(gòu)造函數(shù)產(chǎn)生Test類的對象a,并將x的值改為24,給a的私有數(shù)據(jù)成員n賦值56

cout<<""<<a.func()<<""<<b.func()<<""<<c.func()<<endl;

//輸出:25582525242424}真題在函數(shù)中聲明的靜態(tài)變量【B】

A.在函數(shù)體中可見,函數(shù)執(zhí)行結(jié)束時釋放占用的空間B.在函數(shù)體中可見,程序結(jié)束時釋放占用的空間

【分析】函數(shù)中聲明的靜態(tài)變量一直到整個程序結(jié)束時才釋放占用的空間,但它并不是在程序的所有位置都可見。函數(shù)中聲明的靜態(tài)變量僅在函數(shù)體中可見C.在程序中可見,函數(shù)執(zhí)行結(jié)束時釋放占用的空間D.在程序中可見,程序結(jié)束時釋放占用的空間已知類A中的兩個成員函數(shù)f1()和f2(),如果在f1()中不能直接調(diào)用f2(),則下列選項中,正確的是【C】A.f1()和f2()都是靜態(tài)函數(shù)B.f1()不是靜態(tài)函數(shù),f2()是靜態(tài)函數(shù)C.f1()是靜態(tài)函數(shù),f2()不是靜態(tài)函數(shù)

D.f1()和f2()都不是靜態(tài)函數(shù)【分析】在通常情況下,除一種情況外,類的成員函數(shù)之間是允許互相調(diào)用的。具體來說,靜態(tài)函數(shù)與靜態(tài)函數(shù)之間、非靜態(tài)函數(shù)與非靜態(tài)函數(shù)之間是可以相互調(diào)用的,非靜態(tài)成員函數(shù)內(nèi)可以調(diào)用靜態(tài)成員函數(shù),但靜態(tài)成員函數(shù)內(nèi)不能調(diào)用非靜態(tài)成員函數(shù)。下列關(guān)于靜態(tài)成員變量的描述中,正確的是【A】A.靜態(tài)成員變量是類的所有對象所共有的B.靜態(tài)成員變量要在構(gòu)造函數(shù)內(nèi)初始化C.類的每個對象有自己的靜態(tài)成員變量D.靜態(tài)成員變量不能通過類的對象訪問下列關(guān)于靜態(tài)數(shù)據(jù)成員的特性敘述中,錯誤的是(D)A:說明靜態(tài)數(shù)據(jù)成員時,使用關(guān)鍵字static進行修飾B:靜態(tài)數(shù)據(jù)成員要在類外進行初始化C:引用靜態(tài)數(shù)據(jù)成員時,要在靜態(tài)數(shù)據(jù)成員名前加<類名>和作用域運算符D:靜態(tài)數(shù)據(jù)成員是所有對象的共享成員

注意:這里的“所有對象”應(yīng)該是:所有類對象.靜態(tài)數(shù)據(jù)成員是類的所有對象共享的數(shù)據(jù)下列關(guān)于對靜態(tài)數(shù)據(jù)成員的描述中,正確的是(B)A:靜態(tài)數(shù)據(jù)成員不能用public控制符修飾B:靜態(tài)數(shù)據(jù)成員可以直接用類名或者對象名來調(diào)用C:靜態(tài)數(shù)據(jù)成員不可以被類的對象調(diào)用D:靜態(tài)數(shù)據(jù)成員不能用private控制符修飾下列描述錯誤的是(A)。A:在創(chuàng)建對象前,靜態(tài)成員不存在B:靜態(tài)成員是類的成員C:靜態(tài)成員不能是虛函數(shù)D:靜態(tài)成員函數(shù)不能直接訪問非靜態(tài)成員下面對靜態(tài)數(shù)據(jù)成員的描述中,正確的是(C)A:類的不同對象有不同的靜態(tài)數(shù)據(jù)成員值B:類的每個對象都有自己的靜態(tài)數(shù)據(jù)成員C:靜態(tài)數(shù)據(jù)成員是類的所有對象共享的數(shù)據(jù)D:靜態(tài)數(shù)據(jù)成員不能通過類的對象調(diào)用四、變量及對象的生存期和作用域?qū)τ陟o態(tài)變量,如果沒有進行初始化,系統(tǒng)會自動初始化為0。局部變量如果沒有進行初始化,則其值是隨機的。而局部變量,如在函數(shù)內(nèi)或程序塊內(nèi)說明的變量,被分配到局部數(shù)據(jù)區(qū),如棧區(qū)等。這種分配是臨時的,一旦該函數(shù)體或程序塊運行結(jié)束,所分配的空間就會被撤銷。局部變量的生存期從被說明處開始,到所在程序塊結(jié)束處結(jié)束。使用new運算符創(chuàng)建的變量具有動態(tài)生存期。從聲明處開始,直到用delete運算符釋放存儲空間或程序結(jié)束時,變量生存期結(jié)束類的對象在生成時調(diào)用構(gòu)造函數(shù),在消亡時調(diào)用析構(gòu)函數(shù),在這兩個函數(shù)調(diào)用之間即是對象的生存期真題下列說法不正確的是(A)A:主函數(shù)main中定義的變量在整個文件或程序中有效

主函數(shù)main中定義的變量只在主函數(shù)中有效B:不同函數(shù)中,可以使用相同名字的變量C:形式參數(shù)是局部變量D:在一個函數(shù)內(nèi)部,可以在復(fù)合語句中定義變量,這些變量只在復(fù)合語句中有效五、常量成員和常引用成員常量的賦值,只能在類體外#include<iostream>#include<string>usingnamespacestd;classPerson{

private:

constintage;//常量,這里不允許直接在類里賦值,如:constintage=3;

public:

Person();

intgetAge(){

returnage;

}};//必需用構(gòu)造函數(shù)的初始化列表進行給const進行初始化Person::Person():age(33){}intmain(){

Personp1;

cout<<p1.getAge();}在類中,也可以使用const關(guān)鍵字定義成員變量和成員函數(shù),甚至是類的對象。由關(guān)鍵字const修飾的類成員變量稱為類的常量成員變量。類的常量成員變量必須進行初始化,而且只能通過構(gòu)造函數(shù)的成員初始化列表的方式進行。使用const修飾的函數(shù)稱為常量函數(shù)。定義類的對象時如果在前面添加const關(guān)鍵字,則該對象稱為常量對象。1、定義常量對象或常量成員變量的一般格式如下:

const數(shù)據(jù)類型常量名=表達式;

如:constintgetAge();2、定義常量函數(shù)的格式如下:

類型說明符函數(shù)名(參數(shù)表)const;

如:intgetAge()const;在對象被創(chuàng)建以后,其常量成員變量的值就不允許被修改,只可以讀取其值。對于常量對象,只能調(diào)用常量函數(shù)??傊A砍蓡T變量的值不能修改,常量對象中的各個屬性值均不能修改說明常量對象后,不能通過常量對象調(diào)用普通成員函數(shù)constPersonp;//定義了p為常量對象p.getAge();//如果在Person中這個getAge為非常量的話,就會報錯六、成員對象和封閉類一個類的成員變量如果是另一個類的對象,則該成員變量稱為“成員對象”。這兩個類為包含關(guān)系。包含成員對象的類叫作封閉類。例如,有類A和類B,在類B中定義了一個成員變量v,v的類型是類A;或者在類B中定義了一個函數(shù),返回值類型是類A,則類A和類B是包含關(guān)系,更確切地說,類B包含類A,類B即是封閉類。程序2-2中定義的類Student和類myDate,就是包含關(guān)系的類,類Student是封閉類當(dāng)生成封閉類的對象并進行初始化時,它包含的成員對象也需要被初始化,需要調(diào)用成員對象的構(gòu)造函數(shù)。在定義封閉類的構(gòu)造函數(shù)時,需要添加初始化列表,指明要調(diào)用成員對象的哪個構(gòu)造函數(shù)。在封閉類構(gòu)造函數(shù)中添加初始化列表的格式如下:封閉類名::構(gòu)造函數(shù)名(參數(shù)表):成員變量1(參數(shù)表),成員變量2(參數(shù)表),…{…}初始化列表中的成員變量既可以是成員對象,也可以是基本數(shù)據(jù)類型的成員變量。對于成員對象,初始化列表的“參數(shù)表”中列出的是成員對象構(gòu)造函數(shù)的參數(shù)(它指明了該成員對象如何初始化)。先調(diào)用成員對象的構(gòu)造函數(shù),再調(diào)用封閉類對象的構(gòu)造函數(shù)。如果封閉類的對象是用默認復(fù)制構(gòu)造函數(shù)初始化的,那么它包含的成員對象也會用復(fù)制構(gòu)造函數(shù)初始化七、友元友元實際上并不是面向?qū)ο蟮奶卣鳎菫榱思骖機語言程序設(shè)計的習(xí)慣與C++友元的概念破壞了類的封裝性和信息隱藏,但有助于數(shù)據(jù)共享,能夠提高程序執(zhí)行的效率。信息隱藏的特點,而特意增加的功能。這是一種類成員的訪問權(quán)限。在友元函數(shù)中可以訪問類的私有成員,這是它的目的友元使用關(guān)鍵字friend標(biāo)識。在類定義中,當(dāng)friend出現(xiàn)在函數(shù)說明語句的前面時,表示該函數(shù)為類的友元函數(shù)。一個函數(shù)可以同時說明為多個類的友元函數(shù),一個類中也可以有多個友元函數(shù)。當(dāng)friend出現(xiàn)在類名之前時,表示該類為類的友元類在定義一個類的時候,可以把一些函數(shù)(包括全局函數(shù)和其他類的成員函數(shù))聲明為“友元”,這樣那些函數(shù)就成為本類的友元函數(shù)。在友元函數(shù)內(nèi)部可以直接訪問本類對象的私有成員。在類定義中,將一個全局函數(shù)聲明為本類友元函數(shù)的格式如下:friend返回值類型函數(shù)名(參數(shù)表);當(dāng)有某類A的定義后,將類A的成員函數(shù)說明為本類的友元函數(shù)的格式如下:friend返回值類型類A::類A的成員函數(shù)名(參數(shù)表);不能把其他類的私有成員函數(shù)聲明為友元函數(shù)。友元函數(shù)不是類的成員函數(shù),但允許訪問類中的所有成員。在函數(shù)體中訪問對象成員時,必須使用“對象名.對象成員名”的方式。友元函數(shù)不受類中的訪問權(quán)限關(guān)鍵字限制,可以把它放在類的公有、私有、保護部分,結(jié)果是一樣的。直接看例子吧#include<iostream>#include<cmath>usingnamespacestd;classPixel;//前向引用聲明,因為Test中有Pixel,如果把Pixel類寫到這里,那么這句話可以去掉classTest{

public:

voidprintX(Pixelp);//用到了類Pixel};classPixel{

private:

intx,y;//私有的成員變量,可以通過友元函數(shù)訪問到私有友元變量

public:

Pixel(intx0,inty0){

x=x0;

y=y0;

}

voidprintxy(){

cout<<"pixel:("<<x<<","<<y<<")"<<endl;

}

frienddoublegetDist(Pixelp1,Pixelp2);//友元函數(shù)

friendvoidTest::printX(Pixelp);//友元函數(shù)};voidTest::printX(Pixelp){

cout<<"x="<<p.x<<"\ty="<<p.y<<endl;//訪問類Pixel的私有成員

return;}doublegetDist(Pixelp1,Pixelp2)

{//友元函數(shù)在類體外定義

doublexd=double(p1.x-p2.x);//使用類Pixel的私有成員x

doubleyd=double(p1.y-p2.y);//使用類Pixel的私有成員y

returnsqrt(xd*xd+yd*yd);//兩點間距離}intmain(){

Pixelp1(0,0),p2(10,10);

p1.printxy();

p2.printxy();

cout<<"(p1,p2)間距離="<<getDist(p1,p2)<<endl;

Testt;

cout<<"從友元函數(shù)中輸出--"<<endl;

t.printX(p1);//通過對象調(diào)用類的成員函數(shù)

t.printX(p2);//通過對象調(diào)用類的成員函數(shù)

return0;}友元類如果將一個類B說明為另一個類A的友元類,則類B中的所有函數(shù)都是類A的友元函數(shù),在類B的所有成員函數(shù)中都可以訪問類A中的所有成員。在類定義中聲明友元類的格式如下:friendclass類名;類A是類B的友元,類A的成員函數(shù)可以訪問類B的對象的任何成員友元類的關(guān)系是單向的。若說明類B是類A的友元類,不等于類A也是類B的友元類。友元類的關(guān)系不能傳遞,即若類B是類A的友元類,而類C是類B的友元類,不等于類C是類A的友元類。

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論