版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
計算機二級C++考試復習資料(全)
一、C++概述
(一)發(fā)展歷史
1980年,BjarneStroustcup博士開始著手創(chuàng)立一種模擬語言,可以具有面向?qū)ο蟮?/p>
程序設(shè)計特色。在當時,面向?qū)ο缶幊踢€是一種比較新的理念,Stroustrup博士并不是
從頭開始設(shè)計新語言,而是在C語言的基礎(chǔ)上進行創(chuàng)立。這就是C++語言。
1985年,C++開始在外面慢慢流行。通過數(shù)年的發(fā)展,C++已經(jīng)有了多種版本。為
次,ANSI和ISO的聯(lián)合委員會于1989年著手為C++制定原則。1994年2月,該委員
會出版了第一份非正式草案,1998年正式推出了C++的國際原則。
(二)C利C++
C++是C的超集,也可以說C是C++的子集,由于C先出現(xiàn)。按常理說,C++編譯
器可以編譯任何C程序,不過C和C++還是有某些小差異。
例如C++增長了C不具有的關(guān)鍵字。這些關(guān)鍵字能作為函數(shù)和變量的標識符在C
程序中使用,盡管C++包括了所有的C,但顯然沒有任何C++編譯器能編譯這樣的C程
序。
C程序員可以省略函數(shù)原型,而C++不可以,一種不帶參數(shù)的C函數(shù)原型必須把
void寫出來。而C++可以使用空參數(shù)列表。
C++中new和delete是對內(nèi)存分派的運算符,取代了C中的malloc和free。
原則C++中的字符串類取代了C原則C函數(shù)庫頭文獻中的字符數(shù)組處理函數(shù)。
C++中用來做控制態(tài)輸入輸出的iostream類庫替代了原則C中的stdio函數(shù)庫。
C++中的try/catch/throw異常處理機制取代了原則C中的setjmpO和longjmpO函數(shù)。
二、關(guān)鍵字和變量
C++相對與C增長了某些關(guān)鍵字,如下:
typenamebooldynamic_castmutablenamespace
static_castusingcatchexplicitnew
virtualoperatorfalseprivatetemplate
volatileconstprotectedthiswchar_t
const_castpublicthrowfriendtrue
reinterpiet_casttry
bitorxor_eand_eqcomplor_eq
not_eqbitand
在C++中還增長了bool型變量和wchar.t型變量:
布爾型變量是有兩種邏輯狀態(tài)的變量,它包括兩個值:真和假。假如在體現(xiàn)式中使
用了布爾型變量,那么將根據(jù)變量值的真假而賦予整型值1或0。要把一種整型變量轉(zhuǎn)
換成布爾型變量,假如整型值為0,則其布爾型值為假;反之假如整型值為非0,則其
布爾型值為真。布兒型變量在運行時一般用做標志,例如進行邏輯測試以變化程序流程。
#includeiostream.h
intmain()
(
boolflag;
flag=truc;
if(flag)cout<return0;
C++中還包括wchar」數(shù)據(jù)類型,wchar」也是字符類型,不過是那些寬度超過8位
的數(shù)據(jù)類型。許多外文字符集所含的數(shù)目超過256個,char字符類型無法完全囊括。
wchar_t數(shù)據(jù)類型一般為16位。
原則C++的iostream類庫中包括了可以支持寬字符的類和對象。用wout替代coul
即可。
#includeiostream.h
intmain()
(
wchar_twc;
wc-b';
wout<wc='y';
wout<wc-e1;
wout<return0;
)
闡明一下:某些編譯器無法編譯該程序(不支持該數(shù)據(jù)類型)。
三、強制類型轉(zhuǎn)換
有時候,根據(jù)體現(xiàn)式的需要,某個數(shù)據(jù)需要被當成此外的數(shù)據(jù)類型來處理,這時,
就需要強制編譯器把變量或常數(shù)由中明時的類型轉(zhuǎn)換成需要的類型。為此,就要使用強
制類型轉(zhuǎn)換闡明,格式如下:
int*iptr=(int*)&table;
體現(xiàn)式的前綴(山伊)就是老式C風格的強制類型轉(zhuǎn)換闡明(typecast),又可稱為強制
轉(zhuǎn)換闡明(cast)。強制轉(zhuǎn)換闡明告訴編譯器把體現(xiàn)式轉(zhuǎn)換成指定的類型。有些狀況下強制
轉(zhuǎn)換是禁用的,例如不能把一種構(gòu)造類型轉(zhuǎn)換成其他任何類型。數(shù)字類型和數(shù)字類型、
指針和指針之間可以互相轉(zhuǎn)換。當然,數(shù)字類型和指針類型也可以互相轉(zhuǎn)換,但一般認
為這樣做是不安全并且也是沒必要的。強制類型轉(zhuǎn)換可以防止編譯器的警告。
longintel=123;
shorti=(int)el;
floatm=34.56;
inti=(int)m;
上面兩個都是C風格的強制類型轉(zhuǎn)換,C++還增長了一種轉(zhuǎn)換方式,比較一下上面
和下面這個書寫方式的不一樣:
longintel=123;
shorti=int(el);
floatm=34.56;
inti=int(m);
使用強制類型轉(zhuǎn)換的最大好處就是:嚴禁編譯器對你故意去做的事發(fā)出警告。入過,
運用強制類型轉(zhuǎn)換闡明使得編譯器的類型檢查機制失效,這不是明智的選擇。一般,是
不倡導進行強制類型轉(zhuǎn)換的。除非不可防止,如要調(diào)用malloc。函數(shù)時要用的void型指
針轉(zhuǎn)換成指定類型指針。
四、原則輸入輸出流
在C語言中,輸入輸出是使用語句scanf()和prin【f()來實現(xiàn)的,而C++中是使用類
來實現(xiàn)的。
#includeioslream.h
main?!–++中main。函數(shù)默認為int型,而C語言中默認為void型。
inta;
cout<
cin?a;/*輸入一種數(shù)值*/
cout<return0;
cin,cout,endl對象,他們自身并不是C++語言的泡成部分。雖然他們已經(jīng)是ANSI
原則C++中被定義,不過他們不是語言的內(nèi)在構(gòu)成部分。在C++中不提供內(nèi)在的輸入輸
出運算符,這與其他語言是不一樣的。輸入和輸出是通過C++類來實現(xiàn)的,cin和cout
是這些類的實例,他們是在C++語言的外部實現(xiàn)。
在C++語言中,有了一種新的注釋措施,就是力二在該行〃后的所有闡明都被編譯
器認為是注釋,這種注釋不能換行。C++中仍然保留了老式C語言的注釋風格/*……*/。
C++也可采用格式化輸出的措施:
#includeiostream.h
intmain()
inta;
cout<
cin?a;
cout<
五、函數(shù)重載
在C++中,容許有相似的函數(shù)名,不過它們的參數(shù)類型不能完全相似,這樣這些函
數(shù)就可以互相區(qū)別開來。而這在C語言中是不容許的。
1.參數(shù)個數(shù)不一樣
#includeiostream.h
voida(int,int);
voida(int);
intmain()
a(5);
a(6,7);
return0;
)
voida(inti)
cout<}
voida(inti,intj)
cout<}
2.參數(shù)格式不一樣
#includeiostream.h
voida(int,int);
voida(int,float);
intmain()
{
a(5,6);
a(6,7.0);
return0;
)
voida(inti,intj)
{
cout<}
voida(inti,floatj)
(
cout<}
六、變量作用域
C++語言中,容許變量定義語句在程序中的任何地方,只要在是使用它之前就可以;
而C語言中,必須要在函數(shù)開頭部分。并且C++容許反復定義變量,C語言也是做不到
這一點的。看下面的程序:
#includciostrcam.h
inta;
intmain()
(
cin?a;
for(inti=l;i<=l();i++)//C語言中,不容許在這里定義變量
(
staticinta=0;〃C語言中,同一函數(shù)塊,不容許有同名變量
a+=i;
cout?::a?<}
return0;
)
七、new和delete運算符
在C++語言中,仍然支持malloc。和free。來分派和釋放內(nèi)存,同步增長了new和
delete來管理內(nèi)存。
1.為固定大小的數(shù)組分派內(nèi)存
#includeiostream.h
intmain()
(
int*birlhday二newint[3];
birthday[01=6;
birthday[l]=24;
birthday[2]=1940;
cout<<delete[]birlhday;〃注意這兒
return0;
}
在刪除數(shù)組時,delete運算符后要有一對方括號。
2.為動態(tài)數(shù)組分派內(nèi)存
#includeiostream.h
#includcstdlib.h
intmain()
(
intsize;
cin?sizc;
int*array=newint|size|;
for(inti=O;iarray[i]=rand();
for(i=0;icout?'\n'<delete[]array;
return0;
)
八、引用型變量
在C++中,引用是一種常常使用的概念。引用型變量是其他變量的一種別名,我們
可以認為他們只是名字不相似,其他都是相似的。
1.引用是一種別名
C++中的引用是其他變量的別名。申明一種引用型變量,需要給他一種初始化值,
在變量的生存周期內(nèi),該值不會變化。&運算符定義了一種引用型變量:
inta;
inl&b=a;
先申明一種名為a的變量,它尚有一種別名b。我們可以認為是一種人,有一種真
名,一種外號,后來不管是喊他a還是b,都是叫他這個人。同樣,作為變量,后來對
這兩個標識符操作都會產(chǎn)生相似的效果。
#includeiostream.h
intmain()
(
inta=123;
int&h=a;
cout<a++;
cout<b++;
cout<return0;
)
2.引用的初始化
和指針不一樣,引用變量的值不可變化。引用作為真實對象的別名,必須進行初始
化,除非滿足下列條件之一:
(I)引用變量被申明為外部的,它可以在任何地方初始化
(2)引用變量作為類的組員,在構(gòu)造函數(shù)里對它進行初始化
(3)引用變量作為函數(shù)申明的形參,在函數(shù)調(diào)用時,用調(diào)用者的實參來進行初始化
3.作為函數(shù)形參的引用
引用常常被用作函數(shù)的形參。以引用替代拷貝作為形參的長處:
引用防止了傳遞大型數(shù)據(jù)構(gòu)造帶來的額外開銷
引用不必象指針那樣需要使用"口,等運算符
#includeiostream.h
voidfunc1(sp);
voidfunc2(s&p);
structs
(
intn;
chartext[101;
);
intmain()
(
staticsstr={123,China};
fund(str);
func2(str);
return0;
)
voidfuncl(sp)
(
cout<cout<)
voidfunc2(s&p)
{
cout<cout<)
從表面上看,這兩個函數(shù)沒有明顯區(qū)別,不過他們所花的時間卻有很大差異,func2()
函數(shù)所用的時間開銷會比func2()函數(shù)少諸多。它們尚有一種差異,假如程序遞歸funcl(),
伴隨遞歸的深入,會由于棧的耗盡而瓦解,但func2()沒有這樣的擔憂。
4.以引用方式調(diào)用
當函數(shù)把引用作為參數(shù)傳遞給另一種函數(shù)時,被調(diào)用函數(shù)將直接對參數(shù)在調(diào)用者中
的拷貝進行操作,而不是產(chǎn)生一種局部的拷貝(傳遞變量自身是這樣的)。這就稱為以引
用方式調(diào)用。把參數(shù)的值傳遞到被調(diào)用函數(shù)內(nèi)部的拷貝中則稱為以傳值方式調(diào)用。
#includeiostream.h
voiddisplay(constD£tc&,constchar*);
voids(Date&,Date&);
structDate
(
intmonth,day,year;
};
intmain()
{
staticDatenow={2,23,90);
staticDatethen={9,10,60);
display(now,Now:);
display(then,Then:);
s(now,thcn);
display(now,No\v:);
display(then,Thcn:);
return0;
voids(Date&dt1,Date&dt2)
{
Datesave;
save=dll;
出1=出2;
dt2=save;
I
voiddisplay(constDate&dt,constchar*s)
{
cout<cout<)
5.以引用作為返回值
#includeiostream.h
structDale
(
intmonth,day,year;
);
Datebirthdays!1=
{
(12,12,60);
{10,25,85);
{5,20,73};
};
constDate&getdate(intn)
(
returnbirthdays[n-1];
)
intmain()
(
intdt=l;
while(dt!=0)
(
cout<cin?dt;
if(dt>0&&dt<4)
(
constDate&bd=getdate(dt);
cout<}
)
return0;
)
程序都很簡樸,就不講解了
C++輔導筆記:類的設(shè)計、構(gòu)造函數(shù)和析構(gòu)函數(shù)
一、類的設(shè)計
1?類的申明
class類名
{
private:〃私有
public:〃公有
};
2.類的組員
一般在C++類中,所有定義的變量和函數(shù)都是類的組員。假如是變量,我們就叫它
數(shù)據(jù)組員假如是函數(shù),我們就叫它組員函數(shù)。
3.類組員的可見性
private和public訪問控制符決定了組員的可見性,由一種訪問控制符設(shè)定的可訪問
狀態(tài)將一直持續(xù)到下一種訪問控制符出現(xiàn),或者類申明的結(jié)束。私有組員僅能被同一種
類中的組員函數(shù)訪問,公有組員既可以被同一類中的組員函數(shù)訪問,也可以被其他已經(jīng)
實例化的類中函數(shù)訪問。當然,這也有例外的狀況,這是后來要討論的友元函數(shù)。
類中默認的數(shù)據(jù)類型是private,構(gòu)造中的默認類型是public。一般狀況下,變量都
作為私有組員出現(xiàn),函數(shù)都作為公有組員出現(xiàn)。
類中尚有一種訪問控制符protected,叫保護組員,后來再闡明。
4.初始化
在申明一種類的對象時,可以用圓括號()包括一種初始化表。
看下面一種例子:
#includeiostream.h
classBox
(
private:
intheight,vvidth.depth;//3個私有數(shù)據(jù)組員
public:
Box(int,int,int);
~Box();
intvolume。;〃組員函數(shù)
I;
Box::Box(inthtjntwd,intdp)
(
height=ht;
width二wd;
depth=dp;
I
Box::~Box()
(
//nothing
)
intBox::volume()
returnheight*width*depth;
1
intmain()
Boxthisbox(3,4,5);〃申明一種類對象并初始化
cout<return0;
)
當一種類中沒有private組員和protected組員時,也沒有虛函數(shù),并且不是從其他
類中派生出來的,可以用“來初始化。(后來再講解)
5.內(nèi)聯(lián)函數(shù)
內(nèi)聯(lián)函數(shù)和一般函數(shù)的區(qū)別是:內(nèi)聯(lián)函數(shù)是在編譯過程中展開的。一般內(nèi)聯(lián)函數(shù)必
須簡短。定義類的內(nèi)聯(lián)函數(shù)有兩種措施:一種和C語言同樣,在定義函數(shù)時使用關(guān)鍵字
inline。如:
inlineintBox::vokime()
{
returnheigh1*widlh*deplh;
I
尚有一種措施就是直接在類申明的內(nèi)部定義函數(shù)體,而不是僅僅給出一種函數(shù)原
型。我們把上面的函數(shù)簡化一下:
#includciostream.h
classBox
(
private:
intheight,width,depth;
public:
Box(inthtjntwd,intdp)
(
height=ht;
width=wd;
depth=dp;
)
~Box();
intvolumeO
(
returnheight*width*depth;
)
};
intmain()
(
Boxthisbox(3,4,5);//申明一種類對象并初始化
cout<return0;
)
這樣,兩個函數(shù)都默認為內(nèi)聯(lián)函數(shù)了。
二、構(gòu)造函數(shù)
什么是構(gòu)造函數(shù)?通俗的講,在類中,函數(shù)名和類名相似的函數(shù)稱為構(gòu)造函數(shù)。上
面的Box。函數(shù)就是構(gòu)造函數(shù)。C++容許同名函數(shù),也就容許在一種類中有多種構(gòu)造函
數(shù)。假如一種都沒有,編譯器將為該類產(chǎn)生一種默認的構(gòu)造函數(shù),這個構(gòu)造函數(shù)也許會
完畢某些工作,也也許什么都不做。
絕對不能指定構(gòu)造函數(shù)的類型,雖然是void型都不可以。實際上構(gòu)造函數(shù)默認為
void型。
當一種類的對象進入作用域時,系統(tǒng)會為其數(shù)據(jù)組員分派足夠的內(nèi)存,不過系統(tǒng)不
一定將其初始化。和內(nèi)舒數(shù)據(jù)類型對象同樣,外部對象的數(shù)據(jù)組員總是初始化為0。局
部對象不會被初始化。構(gòu)造函數(shù)就是被用來進行初始化工作的。當自動類型的類對象離
開其作用域時,所站用的內(nèi)存將釋放回系統(tǒng)。
看上面的例子,構(gòu)造函數(shù)Box。函數(shù)接受三個整型擦黑素,并把他們賦值給立方體
對象的數(shù)據(jù)組員。
假如構(gòu)造函數(shù)沒有參數(shù),那么申明對象時也不需要括號。
1.使用默認參數(shù)的構(gòu)造函數(shù)
當在中明類對象時,假如沒有指定參數(shù),則使用默認參數(shù)來初始化對象。
#includeiostream.h
classBox
(
private:
intheight,width,depth;
public:
Box(intht=2,intwd=3,intdp=4)
(
height=ht;
width=wd;
depth=dp;
)
~Box();
intvolumc()
{
returnheight*width*depth;
)
);
intmain()
(
Boxthisbox(3,4,5);/砌始化
Boxdefaulbox;〃使用默認參數(shù)
cout<cout<
return0;
I
2.默認構(gòu)造函數(shù)
沒有參數(shù)或者參數(shù)都是默認值的構(gòu)造函數(shù)稱為默認構(gòu)造函數(shù)。假如你不提供構(gòu)造函
數(shù),編譯器會自動產(chǎn)生一種公共的默認構(gòu)造函數(shù),這個構(gòu)造函數(shù)什么都不做。假如至少
提供一種構(gòu)造函數(shù),則編譯器就不會產(chǎn)生默認構(gòu)造函數(shù)。
3.重載構(gòu)造函數(shù)
一種類中可以有多種構(gòu)造函數(shù)。這些構(gòu)造函數(shù)必須具有不一樣的參數(shù)表。在一種類
中需要接受不一樣初始化值時,就需要編寫多種構(gòu)造函數(shù),但有時候只需要一種不帶初
始值的空的Box對象。
#includeiostream.h
classBox
(
private:
intheight,width.depth;
public:
Box(){//nothing)
Box(intht=2,intwd=3,intdp=4)
1
height=hl;
width=wd;
depth=dp;
I
~Box();
intvoliimc()
(
returnheighl*width*deplh;
)
I;
intmain()
(
Boxthisbox(3,4,5);//初始化
Boxotherbox;
otherbox=thisbox;
cout<return0;
)
這兩個構(gòu)造函數(shù)一種沒有初始化值,一種有。當沒有初始化值時,程序使用默認值,
即2,3,4o
不過這樣的程序是不好的。它容許使用初始化過的和沒有初始化過的Box對象,但
它沒有考慮當thisbox給otherbox賦值失敗后,volume。該返回什么。很好的措施是,沒
有參數(shù)表的構(gòu)造函數(shù)也把默認值賦值給對象。
classBox
(
intheight,width,depth;
public:
Box()
height=O;widlh=O;depth=();
)
Box(inth(,intwd,intdp)
height=ht;width=wd;depth=dp;
)
intvolume()
{
returnhcight*width*dcpth;
)
I;
這還不是最佳的措旎,更好的措施是使用默認參數(shù),主線不需要不帶參數(shù)的構(gòu)造函
數(shù)。
classBox
(
intheight,width,depth;
public:
Box(intht=O,intwd=0,intdp=O)
(
height=ht;width=wd;depth=dp;
)
intvoliimc()
(
returnheighl*width*deplh;
)
);
三、析構(gòu)函數(shù)
當一種類的對象離開作用域時,析構(gòu)函數(shù)將被調(diào)用(系統(tǒng)自動調(diào)用)。析構(gòu)函數(shù)的名
字和類名同樣,不過要在前面加上~。對一種類來說,只能容許一種析構(gòu)函數(shù),析構(gòu)
函數(shù)不能有參數(shù),并且也沒有返值。析構(gòu)函數(shù)的作用是完畢一種清理工作,如釋放從
堆中分派的內(nèi)存。
我們也可以只給出析構(gòu)函數(shù)的形式,而不給出起詳細函數(shù)體,其效果是同樣的,如
上面的例子。但在有些狀況下,析構(gòu)函數(shù)又是必需的C如在類中從堆中分派了內(nèi)存,則
必須在析構(gòu)函數(shù)中釋放
二級C++輔導筆記:類的轉(zhuǎn)換
C++的內(nèi)部數(shù)據(jù)類型遵照隱式類型轉(zhuǎn)換規(guī)則。假設(shè)某個體現(xiàn)市中使用了?種短整型變
量,而編譯器根據(jù)上下文認為這兒需要是的長整型,則編譯器就會根據(jù)類型轉(zhuǎn)換規(guī)則自
動把它轉(zhuǎn)換成長整型,這種隱式轉(zhuǎn)換出目前賦值、參數(shù)傳遞、返回值、初始化和體現(xiàn)式
中。我們也可認為類提供對應(yīng)的轉(zhuǎn)換規(guī)則。
對一種類建立隱式轉(zhuǎn)換規(guī)則需要構(gòu)造一種轉(zhuǎn)換函數(shù),該函數(shù)作為類的組員,可以把
該類的對象和其他數(shù)據(jù)類型的對象進行互相轉(zhuǎn)換。申明了轉(zhuǎn)換函數(shù),就告訴了編譯器,
當根據(jù)句法鑒定需要類型轉(zhuǎn)換時,就調(diào)用函數(shù)。
有兩種轉(zhuǎn)換函數(shù)。一種是轉(zhuǎn)換構(gòu)造函數(shù);另一種是組員轉(zhuǎn)換函數(shù)。需要采用哪種轉(zhuǎn)
換函數(shù)取決于轉(zhuǎn)換的方向。
一、轉(zhuǎn)換構(gòu)造函數(shù)
當一種構(gòu)造函數(shù)僅有一種參數(shù),且該參數(shù)是不一樣于該類的一種數(shù)據(jù)類型,這樣的
構(gòu)造函數(shù)就叫轉(zhuǎn)換構(gòu)造函數(shù)。轉(zhuǎn)換構(gòu)造函數(shù)把別的數(shù)據(jù)類型的對象轉(zhuǎn)換為該類的一種對
象。和其他構(gòu)造函數(shù)同樣,假如申明類的對象的初始化表同轉(zhuǎn)換構(gòu)造函數(shù)的參數(shù)表相匹
配,該函數(shù)就會被調(diào)用。當在需要使用該類的地方使用了別的數(shù)據(jù)類型,廉價器就會調(diào)
用轉(zhuǎn)換構(gòu)造函數(shù)進行轉(zhuǎn)換。
#includeiostream.h
#includctimc.h
#includestdio.h
classDate
(
intmo,da,yr;
public:
Date(time_t);
voiddisplayO;
);
voidDatc::display()
(
charyear[5];
if(yr<10)
sprintf(ycar,0%d,yr);
else
sprintf(year,%d,yr);
cout<}
Date::Date(time_tnow)
(
tm*tim=localtime(&now);
da=tim->tm_mday;
mo=tim->tm_mon+1:
yr=iim->tm_year;
if(yr>=1OO)yr-=100;
)
intmain()
(
time_tnow=time(0);
Datedt(now);
dt.displayO;
return0;
I
本程序先調(diào)用time。函數(shù)來獲取目前時間,并把它賦給time」對象;然后程序通過
調(diào)用Date類的轉(zhuǎn)換構(gòu)造函數(shù)來創(chuàng)立一種Date對象,該對象由time」對象轉(zhuǎn)換而來Jime」
對象先傳遞給locallime。函數(shù),然后返回一種指向lm構(gòu)造(lime.h文獻中申明)的指針,
然后構(gòu)造函數(shù)把構(gòu)造中的口月年的數(shù)值拷貝給Date對象的數(shù)據(jù)組員,這就完畢了從
time」對象至ljDate對象的轉(zhuǎn)換。
二、組員轉(zhuǎn)換函數(shù)
組員轉(zhuǎn)換函數(shù)把該類的對象轉(zhuǎn)換為其他數(shù)據(jù)類型的對象。在組員轉(zhuǎn)換函數(shù)的申明中
要用到關(guān)鍵字operatoro這樣申明一種組員轉(zhuǎn)換函數(shù):
operatoraaa();
在這個例子中,aaa就是要轉(zhuǎn)換成的數(shù)據(jù)類型的闡明符。這里的類型闡明符可以是
任何合法的C++類型,包括其他的類。如下來定義組員轉(zhuǎn)換函數(shù);
Classname:operatoraaa()
類名標識符是申明了該函數(shù)的類的類型闡明符。上面定義的Date類并不能把該類
的對象轉(zhuǎn)換回lime」型變量,但可以把它轉(zhuǎn)換成一種長整型值,計算從1月1日到目前
的天數(shù)。
#includeiostream.h
classDate
(
intmo,da,yr;
public:
Date(intm,intd,inty){mo=m;da=d;yr=y;)
operatorint();〃申明
};
Date:operatorint()〃定義
(
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31);
intdays=yr-;
days*=365;
days+=(yr-)/4;
for(inti=0;idays+=dys[ij;
days+=da;
returndays;
)
intmain()
|
Datenow(12,24,);
intsince=now;
cout<return0;
)
三、類的轉(zhuǎn)換
上面兩個例子都是C++類對象和內(nèi)部數(shù)據(jù)對象之間的互相轉(zhuǎn)換。也可以定義轉(zhuǎn)換函
數(shù)來實現(xiàn)兩個類對象之間的互相轉(zhuǎn)換。
#includeiostrcam.h
classCustomDate
{
public:
intda,yr;
CustomDate(intd=O,inty=0)(da=d;yr=y;}
voiddisplayO
cout<}
classDate
intmo,da,yr;
public:
Datc(intm=O,intd=O.inty=O){mo=m;da=d;yr=y;J
Date(conslCustomDate&);〃轉(zhuǎn)換構(gòu)造函數(shù)
operatorCustomDatc();〃組員轉(zhuǎn)換函數(shù)
voiddisplayO
{
cout<}
I;
staticintdys[]=(31,28,31,30,31,30,31,31,30,31,30,31};
Date::Date(constCuslomDate&jd)
(
yr=jd.yr;
da=jd.da;
for(mo=0;mo<lI;mo-t-+)
if(da>dys[mo])da-=dys[mo];
elsebreak;
mo++;
)
Date::operatorCustomDateO
(
CustomDatecd(0,yr);
for(inti=0;icd.da+=da;
returncd;
}
intmain()
(
Datedt(12,24,3);
CustomDatecd;
cd二dt;〃調(diào)用組員轉(zhuǎn)換函數(shù)
cd.displayO;
dt=cd;〃調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)
dt.displayO;
return0;
)
這個例子中有兩個類CustomDate和Date,CustomDate型日期包括年份和天數(shù)。
這個例子沒有考慮閏年狀況。不過在實際構(gòu)造一種類時,應(yīng)當考慮到所有問題的也
許性。
在Date里中具有兩種轉(zhuǎn)換函數(shù),這樣,當需要從Dale型變?yōu)镃ustomDale型十,
可以調(diào)用組員轉(zhuǎn)換函數(shù);反之可以調(diào)用轉(zhuǎn)換構(gòu)造函數(shù).
不能既在Date類中定義組員轉(zhuǎn)換函數(shù),又在CustomDate類里定義轉(zhuǎn)換構(gòu)造函數(shù)。
那樣編譯器在進行轉(zhuǎn)換時就不懂得該調(diào)用哪一種函數(shù),從而出錯.
四、轉(zhuǎn)換函數(shù)的調(diào)用
C++里調(diào)用轉(zhuǎn)換函數(shù)有三種形式:第一種是隱式轉(zhuǎn)換,例如編譯器需要一種Date
對象,而程序提供的是CusmmDate對象,編譯器會自動調(diào)用合適的轉(zhuǎn)換函數(shù)。此外兩
種都是需要在程序代碼中明確給出的顯式轉(zhuǎn)換。C++強制類型轉(zhuǎn)換是一種,尚有一種是
顯式調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)和組員轉(zhuǎn)換函數(shù)。下面的程序給出了三中轉(zhuǎn)換形式:
#includeiostream.h
classCustomDatc
(
public:
intda,yr;
CustomDale(intd=(),inty=0)(da=d;yr=y;}
voiddisplayO
(
cout<}
};
classDate
(
intmo,da,yr;
public:
Date(intm,intd,inty)
(
mo=m;da=d;yr=y;
)
operatorCustomDate();
};
Date:operatorCustoinDateO
|
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31);
CustomDatecd(0,yr);
for(inti=0;icd.da+=da;
returncd;
)
intmain()
(
Datedt(11,17,89);
CustomDatecd;
cd=dt;
cd.displayO;
cd=(CustomDate)d【;
cd.displayO;
cd=CustomDate(dt);
cd.displayO;
return0;
五、轉(zhuǎn)換發(fā)生的情形
上面的幾種例子都是通過不能類型對象之間的互相賦值來調(diào)用轉(zhuǎn)換函數(shù),尚有幾種
調(diào)用的也許:
參數(shù)傳遞
初始化
返回值
體現(xiàn)式語句
這些狀況下,均有也許調(diào)用轉(zhuǎn)換函數(shù)。
下面的程序不難理解,就不分析了。
#includeiostream.h
classCustomDate
1
public:
intda,yr;
CustomDateO{}
CustomDate(inty){da=d;yr=y;}
voiddisplayO
{
cout<}
};
classDate
(
intmo,da,yr;
public:
Date(intm,intd,inty){mo=m;da=d;yr=y;}
operatorCustomDateO;
};
Date:operatorCustomDateO
(
staticintdys[]={31,23,31,30,31,30,31,31,30,31,30,31);
CustomDatecd(0,yr);
for(inti=0;icd.da+=da;
returncd;
)
classTester
(
CustomDatecd;
public:
explicitTester(CustomDatec){cd=c;}
voiddisplayO(cd.displayO;}
);
voiddispdatc(CustomDatccd)
cd.displayO;
)
CustomDatertndate()
(
Datedt(9,l1,1);
returndt;
)
intniain()
(
Datedt(12,24,3);
CustomDatecd;
cd=dt;
cd.displayO;
dispdate(dt);
Testerts(dt);
ts.displayO;
cd=rtndate();
cd.displayO;
return0;
)
六、顯式構(gòu)造函數(shù)
注意上面Tester類的構(gòu)造函數(shù)前面有,種explicit修飾符。假如不加上這個關(guān)鍵字,
那么在需要把CustomDate對象轉(zhuǎn)換成Tester對象時,編譯器會把該函數(shù)當作轉(zhuǎn)換構(gòu)造
函數(shù)來調(diào)用。不過有時候,并不想把這種只有一種參數(shù)的構(gòu)造函數(shù)用于轉(zhuǎn)換目的,而僅
僅但愿用它來顯式地初始化對象,此時,就需要在構(gòu)造函數(shù)前加explicit。假如在申明了
Tester對象后來使用了下面的語句將導致一種錯誤:
ts=jd;//error
這個錯誤闡明,雖然Tester類中有一種以Date型變量為參數(shù)的構(gòu)造函數(shù),編譯器
卻不會把它看作是從Date到Tester的轉(zhuǎn)換構(gòu)造函數(shù),由于它的申明中包括/explicit修
飾符。
七、體現(xiàn)式內(nèi)部的轉(zhuǎn)換
在體現(xiàn)式內(nèi)部,假如發(fā)現(xiàn)某個類型和需要的不一致,就會發(fā)生錯誤。數(shù)字類型的轉(zhuǎn)
換是很簡樸,這里就不舉例了。下面的程序是把Date對象轉(zhuǎn)換成長整型值。
#includciostrcam.h
classDate
(
intmo,da,yr;
public:
Date(intm,intd,inty)
(
mo=m;da=d;yr=y;
)
operatorlong();
);
Date::operatorlong()
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31);
longdays=yr;
days*=365;
days+=(yr-1900)/4;〃從191月1日開始計算
for(inti=0;idays+=da;
returndays;
}
intmain()
(
Datetoday(12,24,);
constlongott=123;
longsum=otl+loday;
cout<return0;
}
在體現(xiàn)式中,當需要轉(zhuǎn)換的對象可以轉(zhuǎn)換成某個數(shù)字類型,或者體現(xiàn)式調(diào)用了作用
于某個類的重載運算符時,就會發(fā)生隱式轉(zhuǎn)換。運算符重載后來再學習
二級C++輔導筆記:私有數(shù)據(jù)組員和友元
一、私有數(shù)據(jù)組員的使用
1.取值和賦值組員函數(shù)
面向?qū)ο蟮募s定就是保證所有數(shù)據(jù)組員的私有性,一般我們都是通過公有組員函數(shù)
來作為公共接口來讀取私有數(shù)據(jù)組員的。某些時候,我們稱這樣的函數(shù)為取值和賦值函
數(shù)。
取值函數(shù)的返回值和傳遞給賦值函數(shù)的參數(shù)不必一一匹配所有數(shù)據(jù)組員的類型。
#includciostream.h
classDate
(
intmo,da,yr;
public:
Date(intm,intd,inty){mo=m;da=d;yr=y;}
intgetyear()const{returnyr;}
voidsetycar(inty){yr=y;}
};
intmain()
(
Datedt(4,l,89);
cout<dt.setyear(97);
cout<return0;
I
上面的例子很簡樸,不分析了。要養(yǎng)成這樣的習慣,通過組員函數(shù)來訪問和變化類
中的數(shù)據(jù)。這樣有助于軟件的設(shè)計和維護。例如,變化Date類內(nèi)部數(shù)據(jù)的形式,但仍
然用修改正的getyear()Wsetyear。來提供訪問接口,那么使用該類就不必修改他們的代
碼,僅需要重新編譯程序即可。
2.常量組員函數(shù)
注意上面的程序中g(shù)etyear。被申明為常量型,這樣可以保證該組員函數(shù)不會修改調(diào)
用他的對象。通過加上const修飾符,可以使訪問對象數(shù)據(jù)的組員函數(shù)僅僅完畢不會引
起數(shù)據(jù)變動的那些操作。
假如程序申明某個Date對象為常量的話,那么該對象不得調(diào)用任何非常量型組員
函數(shù),不管這些函數(shù)與否真的試圖修改對象的數(shù)據(jù)。只有把那些不會引起數(shù)據(jù)變化的函
數(shù)都中明為常量型,才可以讓常量對象來調(diào)用。
3.改善的組員轉(zhuǎn)換函數(shù)
下面的程序改善了從Date對象至I」CustomDate對象的組員轉(zhuǎn)換函數(shù),用取值和賦值
函數(shù)取代了使用公有數(shù)據(jù)組員的做法。(此前的程序代碼在上一帖中)
#includeiostream.h
classCustomDate
(
intda,yr;
public:
CustomDate(){)
CustomDate(intd,inty)(da=d;yr=y;}
voiddisplay()const{cout<intgctday()const{returnda;}
voidsetday(intd){da=d;}
};
classDate
(
intmo,da,yr;
public:
Dale(intm,intd,inty){mo=m;da=d;yr=y;}
operatorCustomDate()const;
};
Date::operatorCustoinDate()const
(
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31);
CustomDatecd(0,yr);
intday=da;
for(inti=0;icd.setday(day);
returncd;
)
intmain()
{
Datedt(HJ7,89);
CustomDatecd;
cd=dt;
cd.displayO;
return0;
)
注意上面的程序中Date:operatorCustomDate。申明為常量型,由于這個函數(shù)沒有變
化調(diào)用它對象的數(shù)據(jù),盡管它修改了一種臨時CustomDate對象并將其作為函數(shù)返回值。
二、友元
前面已經(jīng)說過了,私有數(shù)據(jù)組員不能被類外的其他函數(shù)讀取,不過有時候類會容許
某些特殊的函數(shù)直接讀寫其私有數(shù)據(jù)組員。
關(guān)鍵字friend可以讓特定的函數(shù)或者別的類的所有組員函數(shù)對私有數(shù)據(jù)組員進行讀
寫。這既可以維護數(shù)據(jù)的私有性,有可以保證讓特定的類或函數(shù)可以直接訪問私有數(shù)據(jù)。
1.友元類
一種類可以申明另一種類為其友元,這個友元的所有組員函數(shù)都可以讀寫它的私有
數(shù)據(jù)。
#includeiostream.h
classDate;
classCustomDate
(
intda,yr;
public:
CustomDate(intd=O,inty=0){da=d;yr=y;}
voiddisplayOconst{cout<friendDate;〃這兒
};
classDate
(
intmo,da,yr;
public:
Date(intm,intd,inty){mo=m;da=d;yr=y;}
operatorCustomDate();
};
Datc::opcratorCustomDatc()
(
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31};
CustomDatecd(0,yr);
for(inti=0;icd.da+=da;
returncd;
)
intmain()
(
Datedt(11,17,89);
CustomDatecd(dt);
cd.displayO;
return0;
)
在上面的程序中,有這樣一句friendDate;該語句告訴編譯器,Date類的所有組員
函數(shù)有權(quán)訪問CustomDare類的私有組員。由于Dale類的轉(zhuǎn)換函數(shù)需要懂得CustomDate
類的每個數(shù)據(jù)組員,因此真?zhèn)€Date類都被申明為CustomDate類的友元。
2.隱式構(gòu)造函數(shù)
上面程序?qū)ustomDate的構(gòu)造函數(shù)的調(diào)用私有顯示該類需要如下的一種轉(zhuǎn)換構(gòu)造
函數(shù):
CustomDate(Date&dt);
不過唯一的一種構(gòu)造函數(shù)是:CustoniDate(intd=O;inty=0);
這就出現(xiàn)了問題,編譯器要從Date對象構(gòu)造一種CustomDate對象,不過CustomDate
類中并沒有定義這樣的轉(zhuǎn)換構(gòu)造函數(shù)。不過Date類中定義了一種組員轉(zhuǎn)換函數(shù),它可
以把Date對象轉(zhuǎn)換成CustomDate對象。于是編譯器開始搜索CustomDate類,看其與
否有i種構(gòu)造函數(shù),能從一種已存在的CustomDate的對象創(chuàng)立新的CustomDate對象。
這種構(gòu)造函數(shù)叫拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)也只有一種參數(shù),該參數(shù)是它所屬的類的
一種對象,由于CustomDate類中沒有拷貝構(gòu)造函數(shù),于是編譯器就會產(chǎn)生一種默認的
拷貝構(gòu)造函數(shù),該函數(shù)簡樸地把已存在的對象的每個組員拷貝給新對象。目前我們己經(jīng)
懂得,編譯器可以把Date對象轉(zhuǎn)換成CustomDate對象,也可以從已存在的CustomDate
對象生成一種新的CustomDate對象。那么上面提出的問題,編譯器就是這樣做的:它
首先調(diào)用轉(zhuǎn)換函數(shù),從Date對象創(chuàng)立一種隱藏的、臨時的、匿名的CuslomDate對象,
然后用該臨時對象作為參數(shù)調(diào)用默認拷貝構(gòu)造函數(shù),這就生成了?種新的CustomDate
對象。
3.預引用
上面的例子中尚有這樣一句classDate;
這個語句叫做預引用。它告訴編譯器,類Date將在背面定義。編譯器必須懂得這
個信號,由于CustomDate類中引用了Date類,而Date里也引用了CustomDate類,必
須首先申明其中之一。
使用了預引用后,就可以申明未定義的類的友元、指針和引用。不過不可以使用那
些需要懂得預引用的類的定義細節(jié)的語句,如申明該類的一種實例或者任何對該類組員
的引用。
4.顯式友元預引用
也可以不使用預引用,這只要在中明友元的時候加上關(guān)鍵自class就行了。
#includciostrcam.h
classCuslomDate
(
intda,yr;
public:
CustomDate(intd=O,inty=0){da=d;yr=y;}
voiddisplayOconst{cout<friendclassDate;〃這兒,去掉前面的預引用
};
classDate
Date:operatorCustotnDateO
)
intmain()
)
5.友元函數(shù)
一般,除非真的需要,否則并不需要把整個類都設(shè)為另一種類的友元,只需挑出需
要訪問目前類私有數(shù)據(jù)組員的組員函數(shù),將它們設(shè)置為該類的友元即可。這樣的函數(shù)稱
為友元函數(shù)。
下面的程序限制了CustomDatc類數(shù)據(jù)組員的訪問,Date類中只有需要這些數(shù)據(jù)的
組員函數(shù)才有權(quán)讀寫它們。
#includeiostream.h
classCustomDate;
classDate
1
intmo,da,yr;
public:
Date(constCustomDate&);
voiddisplayOconst{cout<);
classCustomDate
{
intda,yr;
public:
CustomDate(intd=0,inty=0){da=d;yr=y;}
friendDate::Date(constCustomDate&);
);
Date::Date(constCustomDate&cd)
(
staticintdys[]={31,28,31,30,31,30,31,31,30,31,30,31};
yr=cd.yr;
da=cd.da;
for(mo=0;mo<11;mo++)
if(da>dys[mo])da-=dys[mo];
elsebreak;
mo++;
)
intmain()
(
Datedt(CustomDate(123,89));
dt.displayO;
return0;
)
6.匿名對象
上面main。函數(shù)中Date對象調(diào)用CustomDate類的構(gòu)造函數(shù)創(chuàng)立了一種匿名
CustomDate對象,然后用該對象創(chuàng)立了?種Date對象。這種使用方法在C++中是常常
出現(xiàn)的。
7.非類組員的友元函數(shù)
有時候友元函數(shù)未必是某個類的組員。這樣的函數(shù)擁有類對象私有數(shù)據(jù)組員的讀寫
權(quán),但它并不是任何類的組員函數(shù)。這個特性在重載運算符時尤其有用。
非類組員的友元函數(shù)一般被用來做為類之間的紐帶。一種函數(shù)假如被兩個類同步申
明為友元,它就可以訪問這兩個類的私有組員。下面的程序闡明了一種可以訪問兩個類
私有數(shù)據(jù)組員的友元函數(shù)是怎樣將在兩個類之間架起橋梁的。
#includeiostream.h
classTime;
classDate
{
intmo,da,yr;
public:
Date(intm,intd,inty){mo=m;da=d;yr=y;}
friendvoiddisplay(constDate&,constTime&);
I;
classTime
(
inthr,min,sec;
public:
Time(inthjntm,ints){hr=h;min=m;sec=s;}
friendvoiddisplay(constDate&,constTime&);
);
voiddisplay(constDate&dt,constTime&tm)
{
cout?dt.mo?7'?dt.da?7'?dt.yr;
cout?'
cout?tm.hr??tm.min??tin.sec;
)
intmain()
(
Datedt(2,16,97);
Timetm(10,55,0);
display(dt,tm);
return0;
)
二級C++輔導筆記:析構(gòu)函數(shù)和this指針
一、析構(gòu)函數(shù)
前面的某些例子都沒有闡明析構(gòu)函數(shù),這是由于所用到的類在結(jié)束時不需要做尤其
的清理工作。下面的程序給出了一新的Date類,其中包括一種字符串指針,用來表達
月份。
#includeiostream.h
#includestring.h
classDate
intmo,da,yr;
char*month;
public:
Date(intm=O,intd=0,inty=O);
-Datc();
voiddisplayOconst;
};
Date::Date(intm,intd,in(y)
{
staticchar*mos[]=
(
January,February,March,April,May,June,
July,August,September,Oclober.November.December
};
mo=m;da=d;yr=y;
if(m!=0)
(
month=ncwchiir[strlcn(mos[ni-1])+1];
strcpy(month,mos[m-l]);
)
elsemonth=0;
)
Date::-Date()
(
delete[]month;
)
voidDate::display()const
(
if(month!=0)cout<}
intmain()
(
Datebirthday(8,11,1979);
birthday.displayO;
return0;
}
在Date對象的構(gòu)造函數(shù)中,首先用new運算符為字符串month動態(tài)分派了內(nèi)存,
然后從內(nèi)部數(shù)組中把月份的名字拷貝給字符串指針month。
析構(gòu)函數(shù)在刪除month指針時,也許會出現(xiàn)某些問題。當然從這個程序自身來看,
沒什么麻煩:不過從設(shè)計一種類的角度來看,當Date類用于賦值時,就會出現(xiàn)問題。
假設(shè)上面的main。修改為“
intmain()
{
Datebirthday(8,11,1979);
Datetoday;
today=birthday;
birthday.displayO;
return0;
這會生成一種名為today的空的Date型變量,并且把birthday值賦給它。假如不尤
其告知編譯器,它會簡樸的認為類的賦值就是組員對組員的拷貝。在上面的程序中,變
量birthday有一種字符型指針month,并且在構(gòu)造函數(shù)里用new運算符初始化過了。當
birthday離開其作用域時,析構(gòu)函數(shù)會調(diào)用delete運算符來釋放內(nèi)存。但同步,當loday
離開它的作用域時,析構(gòu)函數(shù)同樣會對它進行移放操作,而today里的month指針是
birthday里的month指針的一種拷貝。析構(gòu)函數(shù)對同一指針進行了兩次刪除操作,這會
帶來不可預知的后果。
假如假設(shè)today是一種外部變量,而birthday是一種自變量。當birthday離開其作
用域時,就已經(jīng)把對象loday里的monlh指針刪除了。顯然這也是不對的的。
再假設(shè)有兩個初始化的Date變帚,把其中一種的值賦值給另一種:
Datebirthday(8,l1,1979);
Datetoday(12,29,);
today=birthday;
問題就更復雜了,當這兩個變量離開作用域時,birthday中的month的值已經(jīng)通過
賦值傳遞給了loday。而today中構(gòu)造函數(shù)用new運算符給m
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年南昌大學人工智能學院科研助理招聘1人備考題庫附答案詳解
- 2025年營養(yǎng)與疾病測試題及答案
- 2025年護理應(yīng)急預案題庫及答案
- 2025年呼吸內(nèi)科考試題庫及答案
- 廊坊市安次區(qū)(2025年)社區(qū)專職網(wǎng)格員考試題庫及答案
- 2025年計算機技巧測試題及答案
- 2025年解剖學試題解析附答案
- (2025年)c機動車駕駛員模擬考試題附答案
- 2025年ROHS20考試題及答案
- 2025年打油詩考試試題及答案
- 2026廣西桂林醫(yī)科大學人才招聘27人備考題庫(第一批)及參考答案詳解一套
- 2026國家國防科技工業(yè)局所屬事業(yè)單位第一批招聘62人筆試參考題庫及答案解析
- 北京2025年北京教育科學研究院公開招聘筆試歷年參考題庫附帶答案詳解
- 老年患者心理護理實踐
- 2026海姆立克急救法更新要點解讀培訓課件
- 2026年寒假作業(yè)實施方案(第二版修訂):騏驥馳騁勢不可擋【課件】
- 2026年春教科版(新教材)小學科學三年級下冊(全冊)教學設(shè)計(附教材目錄P131)
- 《創(chuàng)新與創(chuàng)業(yè)基礎(chǔ)》課件-項目1 創(chuàng)新認知與思維培養(yǎng)
- 廣東省汕頭市金平區(qū)2024-2025學年九年級上學期期末物理試題(含答案)
- 臨床用血技術(shù)規(guī)范2025年版與2000年版對照學習課件
- 生產(chǎn)樣品合同范本
評論
0/150
提交評論