C++程序员笔试复习概要(一)
第8章?????類和對象的創(chuàng)建
【內(nèi)容提要】
類和對象
構(gòu)造函數(shù)和析構(gòu)函數(shù)
對象數(shù)組與對象指針
靜態(tài)成員
友元
靜態(tài)函數(shù)
?
虛函數(shù)
?
【重點與難點】
8.1?類和對象
8.1.1?類的定義
???????類實質(zhì)上是用戶自定義的一種特殊的數(shù)據(jù)類型,它不僅包含相關(guān)的數(shù)據(jù),還包含能對這些數(shù)據(jù)進行處理的函數(shù),同時,這些數(shù)據(jù)具有隱蔽性和封裝性。類中包含的數(shù)據(jù)和函數(shù)統(tǒng)稱為成員,數(shù)據(jù)稱為數(shù)據(jù)成員,函數(shù)稱為成員函數(shù),它們都有自己的訪問權(quán)限。類定義一般分為兩部分,即說明部分和實現(xiàn)部分。說明部分用于說明該類中的成員,實現(xiàn)部分用于對成員函數(shù)進行定義。
?????????類定義格式:
class?類名
????{
??????private:
????????私有數(shù)據(jù)成員和成員函數(shù)
??????protected:
????????保護數(shù)據(jù)成員和成員函數(shù)
??????public:
????????公有數(shù)據(jù)成員和成員函數(shù)
};
各成員函數(shù)的實現(xiàn)
?????????類成員的訪問控制
類成員有三種不訪問權(quán)限:私有(private)、保護(protected)、公有(public)。
私有成員只能被本類的成員函數(shù)訪問及其友元訪問。當(dāng)聲明中未指定訪問控制時,系統(tǒng)默認(rèn)該成員為私有成員。
保護成員一般情況下與私有成員的含義相同,在類的繼承和派生中與私有成員有不同的含義,保護成員可被本類或派生類的成員函數(shù)訪問,但不能被外部函數(shù)訪問。
公有成員可以被程序中的任何函數(shù)訪問,它提供了外部程序與類的接口功能。
?????????類的數(shù)據(jù)成員與成員函數(shù)
????類定義中聲明數(shù)據(jù)成員的數(shù)據(jù)類型和名稱,不能在類內(nèi)說明數(shù)據(jù)成員的同時為其賦初值,只有在類的對象定義以后才能給數(shù)據(jù)成員賦初值。
對于成員函數(shù)可以在類內(nèi)定義,也可以在類內(nèi)給出函數(shù)原型,然后在類外對成員函數(shù)進行定義。成員函數(shù)在類內(nèi)說明原型,在類外給出定義時其定義格式如下:
返回類型??類名::函數(shù)名(參數(shù)表)
????{ //函數(shù)體
????}
在所定義的函數(shù)名前必須加上類名,以表示該函數(shù)屬于哪個類。類名與函數(shù)名之間必須加上作用域運算符∷。
注意:如果在類的內(nèi)部定義成員函數(shù),該成員函數(shù)即被聲明為內(nèi)聯(lián)函數(shù)。也可以在類中聲明,在類外將該成員函數(shù)定義為內(nèi)聯(lián)函數(shù)。只要在定義前加關(guān)鍵字inline,以顯示定義該成員函數(shù)為內(nèi)聯(lián)函數(shù)。這種函數(shù)一般是小的、頻繁使用的函數(shù)。
內(nèi)聯(lián)函數(shù)的聲明有顯式聲明和隱式聲明兩種形式。
隱式聲明:直接將成員函數(shù)定義在類內(nèi)部
顯示聲明:將內(nèi)聯(lián)函數(shù)定義在類外,其聲明的形式與在類外定義成員函數(shù)的形式類似,但為了使成員函數(shù)起到內(nèi)聯(lián)函數(shù)的作用,在函數(shù)聲明前要加關(guān)鍵字inline,以顯式地聲明這是一個內(nèi)聯(lián)函數(shù)?
8.1.2?對象的定義和使用
對象的定義
類定義只是定義了一種新的數(shù)據(jù)類型,只有定義了類的實例即類的對象以后系統(tǒng)才會為該對象分配存儲空間。對象定義可以在類定義的同時直接完成,即在類定義的最后“}”后直接跟對象名列表;也可以在類定義后要使用該對象時定義。
格式:類名 對象名(參數(shù)列表);
說明:可以同時定義多個對象,之間用逗號隔開。
對象成員的引用
????格式:
對象名.數(shù)據(jù)成員;
對象名.成員函數(shù)(實參表);
說明:
①在引用成員時要注意訪問權(quán)限的控制問題。
????②對于指向?qū)ο蟮闹羔樤谝闷涑蓡T時不能使用“.”運算符。其格式為:
對象名->數(shù)據(jù)成員;
對象名->成員函數(shù)(實參表);
?
8.2?構(gòu)造函數(shù)和析構(gòu)函數(shù)
8.2.1?構(gòu)造函數(shù)
構(gòu)造函數(shù)是一種特殊的成員函數(shù),被聲明為公有成員,其作用是為類的對象分配內(nèi)存空間,進行初始化。
關(guān)于構(gòu)造函數(shù)有以下幾點說明:
①構(gòu)造函數(shù)的名字必須與類的名字相同。
②構(gòu)造函數(shù)沒有返回值,不能定義返回類型,包括void型在內(nèi)。
③對象定義時,編譯系統(tǒng)會自動地調(diào)用構(gòu)造函數(shù)完成對象內(nèi)存空間的分配和初始化工作。
④構(gòu)造函數(shù)是類的成員函數(shù),具有一般成員函數(shù)的所有性質(zhì),可訪問類的所有成員,可以是內(nèi)聯(lián)函數(shù),可帶有參數(shù)表,可帶有默認(rèn)的形參值,還可重載。
⑤如果沒有定義構(gòu)造函數(shù),編譯系統(tǒng)就自動生成一個缺省的構(gòu)造函數(shù),這個缺省的構(gòu)造函數(shù)不帶任何參數(shù),僅給對象開辟存儲空間,不完成對數(shù)據(jù)成員賦初值。此時數(shù)據(jù)成員的值是隨機的。系統(tǒng)自動生成的構(gòu)造函數(shù)的形式為:
類名∷類名()
{
}
8.2.2?析構(gòu)函數(shù)
析構(gòu)函數(shù)也是一種特殊的成員函數(shù),也被聲明為公有成員,其作用是釋放分配給對象的內(nèi)存空間,并做一些善后工作。
①關(guān)于析構(gòu)函數(shù)有以下幾點說明:
②析構(gòu)函數(shù)的名字必須是??~類名。
③析構(gòu)函數(shù)沒有參數(shù)、沒有返回值、不能重載。
④當(dāng)對象撤銷時,系統(tǒng)會自動調(diào)用析構(gòu)函數(shù)完成內(nèi)存空間的釋放和善后工作。
⑤如果沒有定義析構(gòu)函數(shù),系統(tǒng)會自動生成一個缺省的空析構(gòu)函數(shù)。完成善后工作,其形式為:
類名::~類名()
{
}
對于構(gòu)造函數(shù)和析構(gòu)函數(shù)常見用法是在構(gòu)造函數(shù)中用new動態(tài)申請空間,在析構(gòu)函數(shù)中用delete釋放內(nèi)存空間。
8.2.3?拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)是一個特殊的構(gòu)造函數(shù),其作用是用一個已經(jīng)存在的對象初始化本類的新對象。每個類都有一個拷貝構(gòu)造函數(shù),它可以是根據(jù)用戶的需要自定義,也可以由系統(tǒng)自動生成。拷貝構(gòu)造函數(shù)名與類名相同,但參數(shù)是本類對象的引用。拷貝構(gòu)造函數(shù)沒有返回值。
定義拷貝構(gòu)造函數(shù)的格式為:
????類名(類名&對象名)
????{
???????//函數(shù)體
????}
其中,對象名是用來初始化另一個對象的對象的引用。
?
構(gòu)造函數(shù)只在對象被創(chuàng)建時自動調(diào)用,而拷貝構(gòu)造函數(shù)在下列三種情況下會被自動調(diào)用:
①用一個對象去初始化本類的另一個對象時。
②函數(shù)的形參是類的對象,在進行形參和實參的結(jié)合時。
③函數(shù)的返回值是類的對象,函數(shù)執(zhí)行完返回時。?
?
8.2.4?對象成員
?????????定義對象成員
當(dāng)用一個類的對象作為另一個類的成員時,該成員稱為對象成員。聲明對象成員的一般格式為:
???????class?類名{
類名1??對象成員名1;//需要此類在前面已經(jīng)定義或聲明。
...
};
?????????對象成員的初始化
在類中有對象成員時,創(chuàng)建本類的對象則本類的構(gòu)造函數(shù)要調(diào)用其對象成員所在類的構(gòu)造函數(shù),并采用成員初始化列表對對象成員進行初始化。這種類的構(gòu)造函數(shù)的定義格式為:
類名∷類名(參數(shù)總表):對象成員1(形參表),...,對象成員n(形參表)
{?
//構(gòu)造函數(shù)體?
}
?
說明:
對象成員的構(gòu)造函數(shù)的調(diào)用順序由對象成員在類中的聲明順序決定,與成員初始化列表中的順序無關(guān)。析構(gòu)函數(shù)的調(diào)用順序正好與構(gòu)造函數(shù)的調(diào)用順序相反。
?
8.3對象數(shù)組與對象指針
8.3.1?對象數(shù)組
???????對象數(shù)組是指數(shù)組中的每個元素都是一個類的對象。當(dāng)然這些對象屬于同一個類。
?????????定義一維對象數(shù)組的一般格式為:
類名?數(shù)組名[常量表達式];
?????????對象數(shù)組的引用
由于對象數(shù)組的元素是對象,只能訪問其公有成員。引用格式為:
數(shù)組名[下標(biāo)].公有成員
8.3.2?對象指針
???????對象指針就是對象在內(nèi)存中的首地址。指向類類型的指針變量用于存放對象指針。其定義格式為:
???????<類名> * <指針變量名>;
說明:
??????????????可以在定義的同時對該指針變量進行初始化即用“&對象名”的形式取出對象首地址賦給該變量,也可以在使用該指針變量時再對它賦值。
?
8.4?靜態(tài)成員
靜態(tài)成員是指類中用關(guān)鍵字static說明的那些成員。靜態(tài)成員仍然服從訪問控制。
8.4.1靜態(tài)數(shù)據(jù)成員
???????靜態(tài)數(shù)據(jù)成員是指類中用關(guān)鍵字static說明的那些數(shù)據(jù)成員。靜態(tài)數(shù)據(jù)成員屬于類而不屬于某個對象。它實現(xiàn)同類對象之間的數(shù)據(jù)共享。
?????????在類中聲明靜態(tài)數(shù)據(jù)成員時,必須加static說明。
?????????對靜態(tài)數(shù)據(jù)成員初始化只能在類外進行,一般在在類聲明與main()之間的位置。
格式為:
??????????????數(shù)據(jù)類型?類名∷靜態(tài)數(shù)據(jù)成員名=值;
?????????對靜態(tài)數(shù)據(jù)成員的引用可以有兩種形式:
類名∷靜態(tài)數(shù)據(jù)成員
對象名.靜態(tài)數(shù)據(jù)成員
8.4.2靜態(tài)成員函數(shù)
靜態(tài)成員函數(shù)是指類中用關(guān)鍵字static說明的那些成員函數(shù)。可以用靜態(tài)成員函數(shù)在未建立任何對象之前去處理靜態(tài)數(shù)據(jù)成員。靜態(tài)成員函數(shù)只能直接引用該類的靜態(tài)數(shù)據(jù)成員和靜態(tài)成員函數(shù),不能直接引用非靜態(tài)數(shù)據(jù)成員。
???調(diào)用靜態(tài)的兩種形式:
類名∷靜態(tài)函數(shù)名();??或??對象名.靜態(tài)函數(shù)名();
?
8.5?友元
C++引入了友元實現(xiàn)了在類的外部訪問類的私有成員的功能。這樣,即不放棄私有數(shù)據(jù)的安全性,又可在類的外部訪問類的私有成員。但一定程度上說友元破壞了類的封裝性,在使用友元時一定要慎重。友元關(guān)系是單向的,也是不能傳遞的。
8.5.1?友元函數(shù)
???????一個普通函數(shù)作為某個類的友元時即為友元函數(shù)。在該函數(shù)中可以訪問其由friend聲明語句所在的類的對象的私有成員和公有成員。在類中作如下聲明,則說明該函數(shù)不是本類的成員函數(shù),而是友元函數(shù)。
friend?函數(shù)類型?友元函數(shù)名(參數(shù)表);
友元函數(shù)的定義可以在類內(nèi)也可以在類外,在類外定義時不需要加類名和普通函數(shù)定義沒有區(qū)別。通常友元函數(shù)的定義在類外進行。
友元函數(shù)不是類的成員,因而不能直接引用對象成員的名字,也不能通過this指針引用對象的成員,必須通過作為入口參數(shù)傳遞進來的對象名或?qū)ο笾羔榿硪迷搶ο蟮某蓡T。為此,友元函數(shù)一般都帶有一個該類的入口參數(shù)。
8.5.2?友元成員函數(shù)
???????某個類的成員函數(shù)作為另一個類的友元即為友元成員函數(shù)。通過友元成員函數(shù),可以訪問由friend聲明語句所在的類的對象的私有成員和公有成員。
當(dāng)一個類A的成員函數(shù)作為另一個類B的友元函數(shù)時,在類B中的聲明格式為:
???????friend?函數(shù)類型?成員函數(shù)所在類類名::函數(shù)名(參數(shù)表);
8.5.3?友類
???????當(dāng)一個類作為另一個類的友元時即為友類。若類A是類B的友類,則類A中的所有成員函數(shù)都是類B的友元成員函數(shù),所以可以通過對象名訪問B的私有成員和公有成員。
當(dāng)類A為類B的友類時,在類B中的聲明格式為:
firiend?class <友元類名>;?或?friend <友元類名>;
?
8.4 內(nèi)聯(lián)函數(shù)
?1在內(nèi)聯(lián)函數(shù)中,不能含有復(fù)雜的結(jié)構(gòu)控制語句,如switch、for和while等;
?2內(nèi)聯(lián)函數(shù)適合規(guī)模小,通常1-5行語句,但被頻繁調(diào)用 的簡單函數(shù);
?3遞歸函數(shù)不能用作內(nèi)聯(lián)函數(shù);
?4在類結(jié)構(gòu)中,在類體內(nèi)定義的成員函數(shù)都是內(nèi)聯(lián)函數(shù)。
8.6 虛函數(shù)
C++函數(shù)中那些不可以被聲明為虛函數(shù)
常見的不不能聲明為虛函數(shù)的有:普通函數(shù)(非成員函數(shù));靜態(tài)成員函數(shù);內(nèi)聯(lián)成員函數(shù);構(gòu)造函數(shù);友元函數(shù)。
1.為什么C++不支持普通函數(shù)為虛函數(shù)?
普通函數(shù)(非成員函數(shù))只能被overload,不能被override,聲明為虛函數(shù)也沒有什么意思,因此編譯器會在編譯時邦定函數(shù)。
2.為什么C++不支持構(gòu)造函數(shù)為虛函數(shù)?
這個原因很簡單,主要是從語義上考慮,所以不支持。因為構(gòu)造函數(shù)本來就是為了明確初始化對象成員才產(chǎn)生的,然而virtual function主要是為了再不完全了解細(xì)節(jié)的情況下也能正確處理對象。另外,virtual函數(shù)是在不同類型的對象產(chǎn)生不同的動作,現(xiàn)在對象還沒有產(chǎn)生,如何使用virtual函數(shù)來完成你想完成的動作。(這不就是典型的悖論)
3.為什么C++不支持內(nèi)聯(lián)成員函數(shù)為虛函數(shù)?
其實很簡單,那內(nèi)聯(lián)函數(shù)就是為了在代碼中直接展開,減少函數(shù)調(diào)用花費的代價,虛函數(shù)是為了在繼承后對象能夠準(zhǔn)確的執(zhí)行自己的動作,這是不可能統(tǒng)一的。(再說了,inline函數(shù)在編譯時被展開,虛函數(shù)在運行時才能動態(tài)的邦定函數(shù))
4.為什么C++不支持靜態(tài)成員函數(shù)為虛函數(shù)?
這也很簡單,靜態(tài)成員函數(shù)對于每個類來說只有一份代碼,所有的對象都共享這一份代碼,他也沒有要動態(tài)邦定的必要性。
5.為什么C++不支持友元函數(shù)為虛函數(shù)?
因為C++不支持友元函數(shù)的繼承,對于沒有繼承特性的函數(shù)沒有虛函數(shù)的說法。
?
【典型例題】
例題1.下列程序段是否有錯,若有錯請改錯。
#include<iostream.h>
class point---------------------------------------------①
{
???????private:
??????????????int?x,y;
???????public:
??????????????void?setpoint(int,?int);--------------------②
};
int?point::?setpoint(int?xx,?int?yy)????----------------③
{?
???????x=xx;---------------------------------------------?④
???????y=yy;---------------------------------------------?⑤
???????return 1;------------------------------------------?⑥
}
void main()
{
???????point p1;------------------------------------------------------------------------------?⑦
???????p1.setpoint(2,4);---------------------------------------------------------------------?⑧
????cout<<”坐標(biāo)為:(”<<p1.x<<”,”<<p1.y<<”)”<<endl;-------------------------?⑨
}
解答:
這里⑨錯誤,不能在類定義以外直接訪問類的私有成員。要得該點的兩個坐標(biāo),應(yīng)該在類中定義獲取私有成員x,y的公有成員函數(shù),使得可以在類外通過類的公有成員函數(shù)對其私有成員進行間接訪問。所以程序應(yīng)改為:
class point
{
???????private:
??????????????int?x,y;
???????public:
??????????????void?setpoint(int,?int);?????//聲明成員函數(shù)setpoint()的函數(shù)原型
??????????????int?getx();??????//聲明成員函數(shù)getx()的函數(shù)原型
??????????????int?gety();???????//聲明成員函數(shù)gety的函數(shù)原型
};
void point::?setpoint(int?xx,?int?yy)?//定義成員函數(shù)setpoint()
{?
???????x=xx;
???????y=yy;
}
int?point ::?getx()???//定義成員函數(shù)getx()
{??????return x;}
int?point ::?gety()???//定義成員函數(shù)gety
{??????return y;}
?
例題2.在下列函數(shù)原型中,可以作為類student的構(gòu)造函數(shù)的說明的是(??)。
(a)void student(int?age);??????(b)int?student( );??????(c)student(int)const;??????(d)student(int);
解答:
本題主要考查對構(gòu)造函數(shù)的特點的掌握。構(gòu)造函數(shù)的名字必須與類的名字相同。構(gòu)造函數(shù)沒有返回值,不能定義返回類型,包括void型在內(nèi)。構(gòu)造函數(shù)可以是內(nèi)聯(lián)函數(shù),可帶有參數(shù)表,可帶有默認(rèn)的形參值,還可重載。選項a、b均有返回值類型,不能作為構(gòu)造函數(shù)。選項c為常成員函數(shù),構(gòu)造函數(shù)不能為常成員函數(shù)。答案為:d
?
例題3.下列說法正確的是(??)。
(a)????可以定義修改對象數(shù)據(jù)成員的const成員函數(shù)。
(b)????不允許任何成員函數(shù)調(diào)用const對象,除非該成員函數(shù)也聲明為const。
(c)????const對象可以調(diào)用非const成員函數(shù)。
(d)????const成員函數(shù)可以調(diào)用本類的非const成員函數(shù)。
解答:
c++編譯器不允許任何成員函數(shù)調(diào)用const對象,除非該成員函數(shù)本身也聲明為const。聲明const的成員函數(shù)不能修改對象,因為編譯器不允許其修改對象。對const對象調(diào)用非const成員函數(shù)是個語法錯誤。定義調(diào)用同一類實例的非const成員函數(shù)的const成員函數(shù)是個語法錯誤。答案為:b
?
例題4.運行下列程序后,” constructing A!”?和” destructing A!”分別輸出幾次(??)。
#include<iostream.h>
class A
{
???????int?x;
public:
???????A()
???????{cout<<" constructing A!"<<endl;}
???????~A()
???????{cout<<" "<<endl;}
};
void main()
{
???????A?a[2];
???????A *p=new A;
???????delete p;
}
(a)2次,2次??????(b)3次,3次??????(c)1次,3次??????(d)3次,1次
解答:
本題主要考查在什么情況下系統(tǒng)會調(diào)用構(gòu)造函數(shù)與析構(gòu)函數(shù)。在主函數(shù)中定義了一個對象數(shù)組,其中有兩個元素,該數(shù)組中的每個元素都是一個類的對象,所以這里會調(diào)用2次構(gòu)造函數(shù);new A時創(chuàng)建一個A類的對象,所以也會調(diào)用構(gòu)造函數(shù),因此一共調(diào)用3次構(gòu)造函數(shù)。delete p;會撤消new運算分配的空間,它會調(diào)用1次析構(gòu)函數(shù)。主函數(shù)結(jié)束時要釋放數(shù)組所占空間,會調(diào)用2次析構(gòu)函數(shù),因此析構(gòu)函數(shù)也調(diào)用了3次。答案為:b
?
例題5.運行下列程序的結(jié)果為__________________________。
#include<iostream.h>
#include<string.h>
class course
{
???????int?id;
???????char name[50];
public:
???????course(int?csid,char?*csname)
???????{
??????????????cout<<"constructing course!"<<endl;
??????????????id=csid;
??????????????strcpy(name,csname);
???????}
???????~course()
???????{
??????????????cout<<"destructing course!"<<endl;
???????}
???????int?getid()
???????{return id;}
???????char*?getname()
???????{
??????????????return name;
???????}
};
class student
{
???????char name[10];
???????int?age;
???????course c1;
public:
???????student(char *sname,int?sage,int?cid,char?*cname):c1(cid,cname)
???????{
??????????????cout<<"constructing student!"<<endl;
??????????????strcpy(name,sname);
??????????????age=sage;
???????}
???????~student()
???????{
??????????????cout<<"destructing student!"<<endl;
???????}
???????void prints()
???????{
??????????????cout<<"name:"<<name<<endl
?????????????????????<<"age:"<<age<<endl
?????????????????????<<"course id:"<<c1.getid()<<endl
?????????????????????<<"course name:"<<c1.getname()<<endl;
???????}
};
?
void main()
{
???????student st1("tom",23,1,"c++ programming language");
???????st1.prints();
}
解答:
本題主要考查在為含有對象成員的類創(chuàng)建對象時,構(gòu)造函數(shù)的調(diào)用順序,對象成員的初始化問題以及對象撤消時調(diào)用析構(gòu)函數(shù)的順序。對于本程序,在主函數(shù)中創(chuàng)建student類的對象則調(diào)用其構(gòu)造函數(shù)student(),該構(gòu)造啟動時,首先為數(shù)據(jù)成員分配空間,然后根據(jù)在類中聲明的對象成員的順序依次調(diào)用其構(gòu)造函數(shù),在這里調(diào)用course類的構(gòu)造函數(shù),最后才執(zhí)行自己的構(gòu)造函數(shù)的函數(shù)體。析構(gòu)函數(shù)以調(diào)用構(gòu)造函數(shù)相反的順序被調(diào)用。
答案為:
constructing course!
constructing student!
name:tom
age:23
course id:1
course?name:c++ programming language
destructing student!
destructing course!
?
例題6.運行下列程序輸出結(jié)果為_____________________。
#include<iostream.h>
class A{
public:
???????A(int?X){cout<<"ok!";}
???????A(){}
};
int?main()
{
???????A?a[3],a1(3);
???????return 0;
}
解答:
本題主要考查對重載構(gòu)造函數(shù)的理解。這里創(chuàng)建對象數(shù)組時,對數(shù)組的每一個元素都將調(diào)用一次構(gòu)造函數(shù),如果沒有顯式給出數(shù)組元素的初值,則調(diào)用缺省構(gòu)造函數(shù)。而創(chuàng)建對象a1時帶有一個整型參數(shù),所以調(diào)用以整型作為參數(shù)的構(gòu)造函數(shù),它輸出ok!。所以,本題答案為:ok!
?
例題7.運行下列程序結(jié)果為________________________。
#include<iostream.h>
const double PI=3.14159;
class circle
{
???????double r;
??????
public:
???????static?int?num;
???????circle(double);
???????circle(circle &);
???????double?getr();
};
circle::circle(double?i)
{
???????r=i;
}
circle::circle(circle &c)
{
???????num++;
???????cout<<"第"<<num<<"次調(diào)用拷貝構(gòu)造函數(shù)!"<<endl;
??r=c.r*num;
}
double circle::getr()
{
???????return r;
}
double getradius(circle c3)
{
???????return c3.getr();
}
circle fun1()
{
???????circle c4(5);return c4;
}
int?circle::num=0;
void main()
{
???????circle c1(1);
???????cout<<"c1:"<<c1.getr()<<endl;
????circle c2(c1);
????cout<<"c2:"<<c2.getr()<<endl;
????cout<<"c3:"<<getradius(c1)<<endl;
???????circle c4(1);
???????c4=fun1();
???????cout<<"c4:"<<c4.getr()<<endl;
}
?
解答:
本題主要考查在什么情況下會調(diào)用拷貝構(gòu)造函數(shù)。構(gòu)造函數(shù)只在對象被創(chuàng)建時自動調(diào)用,而拷貝構(gòu)造函數(shù)在下列三種情況下會被自動調(diào)用:
①用一個對象去初始化本類的另一個對象時。
②函數(shù)的形參是類的對象,在進行形參和實參的結(jié)合時。
③函數(shù)的返回值是類的對象,函數(shù)執(zhí)行完返回時。?
本題答案為:
c1:1
第1次調(diào)用拷貝構(gòu)造函數(shù)!
c2:1
第2次調(diào)用拷貝構(gòu)造函數(shù)!
c3:2
第3次調(diào)用拷貝構(gòu)造函數(shù)!
c4:15
?
例題8.讀程序?qū)懡Y(jié)果或者程序填空。
#include<iostream.h>
class A
{
???????const?int?i;
???????int?&j;
public:
???????A(int&?var):i(10),j(var)
???????{}
???????void show()
???????{
??????????????cout<<"i:"<<i<<endl
?????????????????????<<"j:"<<j<<endl;
???????}
};
void main()
{
???????int?x=1;
???????A a1(x);
???????a1.show();
}
解答:
本題主要考查對符號常量和引用的理解。常量是不能被賦值的,一旦初始化后,其值就永不改變,引用變量也是不可重新指派的,初始化后,其值就固定不變了。
結(jié)果為:
i:10
j:1
?
例題9.運行下列程序結(jié)果為__________________。
#include<iostream.h>
class?Obj{
???????static?int?i;
public:
???????Obj(){i++;}
???????~Obj(){i--;}
???????static?int?getVal(){return?i;}
};
int?Obj::i=0;
void f (){Obj?ob2;cout<<ob2.getVal();}
int?main(){
???????Obj?ob1;
???????f();
???????Obj*ob3=new?Obj;cout<<ob3->getVal();
???????delete ob3;cout<<Obj::getVal();
???????return 0;
}
解答:
本題主要考查對靜態(tài)數(shù)據(jù)成員的理解。在主函數(shù)中創(chuàng)建對象ob1則調(diào)用該類的構(gòu)造函數(shù),使得靜態(tài)數(shù)據(jù)成員加1,為1;接著調(diào)用函數(shù)f(),在函數(shù)中創(chuàng)建對象ob2,這時再次調(diào)用構(gòu)造函數(shù),使得靜態(tài)成員的值為2,ob2.getVal()返回靜態(tài)數(shù)據(jù)成員i的值,即輸出2。函數(shù)f()結(jié)束,則ob2的生存期結(jié)束,自動調(diào)用其析構(gòu)函數(shù)使靜態(tài)數(shù)據(jù)成員i的值變?yōu)?。接著在主函數(shù)中用new運算符動態(tài)分配存儲空間,又一次調(diào)用構(gòu)造函數(shù)使i加1,所以再次輸出時i的值為2。最后用delete釋放ob3所指的對象空間,則會調(diào)用析構(gòu)函數(shù)使i的值減1,因此輸出i的值為1。本題答案為:221
?
例題10.若類A是類B的友元,類B是類C的友元,則下列說法正確的是(??)。
(a)類B是類C的友元????????????(b)類A是類C的友元
(c)類A,B,C互為友元??????????(d)以上說法都不對
解答:
本題考查對友元關(guān)系的理解。友元關(guān)系是單向的,也是不能傳遞的。答案為:a
?
例題11.當(dāng)輸入為2??3時,下列程序輸出“兩個數(shù)的和為:5”。請將程序補充完整。
#include<iostream.h>
class num
{
???????int?x,y;
public:
???????num(int=0,int=0);
???????_________①____________
};
num::num(int?x,int?y)
{
???????_________②____________
???
????_________③____________
}
int sum(num& n)
{
???????return?n.x+n.y;
}
void main()
{
???????int?i,j;
???????cout<<"請輸入兩個數(shù):"<<endl;
???????cin>>i>>j;
???????________④__________//定義對象num1
???????cout<<"兩數(shù)的和為:"<<sum(num1)<<endl;
}
解答:
本題主要考查友元的應(yīng)用以及對不同作用域變量的引用方法。
答案為:①friend?int?sum(num&);②num::x=x;③num::y=y;④num num1(i,j);
?
【習(xí)題】
一、選擇題
1.下列各項中不能用于聲明類的成員訪問控制權(quán)限的關(guān)鍵字是(??)。
(a)private??????(b)protected??????(c)public??????(d)static
2.下列關(guān)于構(gòu)造函數(shù)的說法錯誤的是(??)。
(a)構(gòu)造函數(shù)的名字必須與類的名字相同。
(b)構(gòu)造函數(shù)可以定義為void類型。
(c)構(gòu)造函數(shù)可以重載、可以帶有默認(rèn)參數(shù)。
(d)構(gòu)造函數(shù)可以由用戶自定義也可以由系統(tǒng)自動生成。
3.有如下類聲明:
class student
{
int?age;
char *name;
};
則student類的成員age是(??)。
(a)公有數(shù)據(jù)成員???????(b)私有數(shù)據(jù)成員??????(c)保護數(shù)據(jù)成員???????(d)私有成員函數(shù)
4.有如下類定義
#include<iostream.h>
class point
{
int?x,y;
public:
point():x(0),y(0){}
point(int?x1,int y1=0):x(x1),y(y1){}
};
若執(zhí)行語句
point a(2),b[3],*c;
則point類的構(gòu)造函數(shù)被調(diào)用的次數(shù)是(??)。
(a)2次??????(b)3次??????(c)4次??????(d)5次
5.在下列哪種情況下不會調(diào)用拷貝構(gòu)造函數(shù)(??)。
(a)用一個對象去初始化本類的另一個對象時。
(b)函數(shù)的形參是類的對象,在進行形參和實參的結(jié)合時。
(c)函數(shù)的返回值是類的對象,函數(shù)執(zhí)行完返回時。?
(d)將類的一個對象賦值給另一個本類的對象時。
6.下列關(guān)于友元的描述錯誤的是(??)。
(a)????友元關(guān)系是單向的且不可傳遞
(b)????在友元函數(shù)中可以通過this指針直接引用對象的私有成員。
(c)????友元可以是一個普通函數(shù)也可以是一個類。
(d)????通過友元可以實現(xiàn)在類的外部對類的私有成員的訪問。
7.有如下程序
#include <iostream>
using namespace std;
class AA{
???????int?n;
public:
???????AA(int?k):n(k){ }
???????int?get( ){ return n;}
???????int?get( )const{ return n+1;}
};
int?main( )
{
???????AA a(5);
???????const AA b(6);
???????cout<<a.get( )<<b.get( );
???????return 0;
}
運行該程序結(jié)果為(??)。
(a)56????????(b)57????????(c)67????????(d)66
8.有如下程序:
#include <iostream.h>
class Test {
public:
Test( ) { n+=2; }
~Test( ) { n-=3; }
static?int?getNum( ) { return n; }
private:
static?int?n;
};
int?Test::n?= 1;
int?main( )
{
Test* p = new Test;
delete p;
cout?<< "n=" <<?Test::getNum( ) <<?endl;
return 0;
}
執(zhí)行后的輸出結(jié)果是(?)。
(a)????n=0???????(b)n=1??????(c)n=2???????(d)n=3
9.下列程序的運行結(jié)果為(??)。
#include<iostream.h>
class A
{
public:
???????static?int?num;
???????A& fun()
???????{
??????????????num++;
??????????????return *this;
???????}
};
int?A::num=0;
void g(A& a)
{
???????cout<<a.fun?().num<<endl;
}
void main()
{
???????A a1;
???????g(a1);
}
(a)0??????(b)1??????(c)2??????(d)3
10.運行下列程序結(jié)果為____________________。
#include<iostream>
#include<iomanip>
using namespace std;
class?MyClass{
public:
???????MyClass(){cout<<'A';}
???????MyClass(char c){cout<<c;}
???????~MyClass(){cout<<'B';}
};
int?main(){
???????MyClass?p1,*p2;
???????p2=new?MyClass('X');
???????delete p2;
???????return 0;
}
執(zhí)行這個程序幕上將顯示輸出______。
(a)ABX???????(b)ABXB???????(c)AXB???????(d)AXBB
?
二、填空題
1.類的成員包括________成員和成員________。
2.釋放對象所占的內(nèi)存空間并完成善后處理工作的是___________函數(shù)。
3.拷貝構(gòu)造函數(shù)以______________作為參數(shù)。
4.用指向?qū)ο蟮闹羔樢脤ο蟪蓡T使用操作符__________。
5.當(dāng)一個對象生成以后,系統(tǒng)就為這個對象定義了一個__________,它指向這個對象的地址。
6.在類中聲明靜態(tài)成員的關(guān)鍵字是___________。
7.非成員函數(shù)應(yīng)聲明為類的____________函數(shù)才能訪問這個類的private成員。
8.C++建立和初始化對象的過程由_______________完成。
9.對于常量數(shù)據(jù)成員和引用數(shù)據(jù)成員的初始化只能通過________________來完成。
10.在類中說明的具有類類型的成員稱為_________________。
11.下列為類的定義語句,是否有錯,若有錯請改正。
class circle --------------------------------------------①
{
???????double r=3;---------------------------------------②
public:----------- ---------------------------------------③
???????circle(double?i) ----------------------------------④
???????{
??????????????r=i; ------------------------------------------⑤
???????}
???????double area();//面積-----------------------------⑥
????double?prm();//周長-----------------------------⑦
???????void?printarea(double); -------------------------⑧
void?printprm(double); -------------------------
}--------------------------------------------------------⑩
//成員函數(shù)的實現(xiàn)
?
12.下列程序輸出結(jié)果為0,1.請將程序補充完整。
#include<iostream.h>
class A{
???????int num;
public:
???????A():num(0){}
???????void set(int num)
???????{ ________①___________}//給A的數(shù)據(jù)成員num賦值
???????int get()
{_________②__-_________}//獲得數(shù)據(jù)成員num的值
};
int?main()
{
???????A?a;
???????cout<<a.get()<<”,”;
???????a.set(1);
???????cout<<a.get()<<endl;
???????return 0;
}
13.下列程序輸出:2,33.4,tom。請將程序補充完整。
#include<iostream.h>
#include<string.h>
class A
{
???????int?i;
????float j;
????char c[20];
public:
????A(int?x, float y, char?ch[]):i(x),j(y)
????{?
??????????????________①__________???//初始化成員c賦值
???????}
???????void?printA()
???????{
??????????????________②___________//輸出三個私有數(shù)據(jù)成員
???????}
};
void main()
{
???????A?a(2,33.4,"tom");
???????a.printA();
}
14.下列程序的輸出結(jié)果為
Object id=0
Object id=1
請將程序補充完整。
#include <iostream.h>
class Point
{
public:
???????Point(int?xx=0,?int?yy=0) {X=xx; Y=yy;?countP++; }
???????Point( ) {?countP--; }
???????int?GetX( ) {return X;}
???????int?GetY( ) {return Y;}
???????static void?GetC( ) {cout<<" Object id="<<countP<<endl;}
private:
???????int?X,Y;
???????static?int?countP;
};
__________________//靜態(tài)數(shù)據(jù)成員的初始化
int?main( )
{
???????Point::GetC( );
???????Point A(4,5);
???????A.GetC( );
???????return 0;
}
15.?插入排序算法的主要思想是:每次從未排序序列中取出一個數(shù)據(jù),插入到已排序序列中的正確位置,InsertSort類的成員函數(shù)sort()實現(xiàn)了插入排序算法,請將畫線處缺失的部分補充完整。
#include<iostream.h>
class?InsertSort{
public:
???????InsertSort(int*a0,int n0):a(a0),n(n0){}//a是數(shù)組首地址,n是數(shù)組元素個數(shù)
???????void sort()
???????{//此函數(shù)假設(shè)已排序序列初始化狀態(tài)只包含a[0],未排序序列初始為a[1]…a[n-1]
??????????????for (int?i=1;i<n;++i)
??????????????{
?????????????????????int?j,t;
?????????????????????for(_______________;j>0;--j)
?????????????????????{
????????????????????????????if(t>a[j-1])break;
????????????????????????????a[j]=a[j-1];
?????????????????????}
?????????????????????a[j]=t;
??????????????}
???????}
protected:
???????int*a,n;//指針a用于存放數(shù)組首地址,n用于存放數(shù)組元素個數(shù)
};
?
三、編程題???
1.?自定義一個正方體類,它具有私有成員x,表示正方體的每個面的正方形的邊長。提供構(gòu)造函數(shù)以及計算正方體的體積和表面積的公有成員函數(shù),并編制主函數(shù),對正方體類進行使用:說明正方體類對象,輸入棱長,計算其體積和表面積并顯示結(jié)果。
?
2.?設(shè)計一個時間類Time,包括3個數(shù)據(jù)成員,時(hour)、分(minute)、秒(second),以及成員函數(shù)用于設(shè)置和讀取時、分、秒,并按上午、下午各12小時或按24小時輸出時間。
?
【參考答案】
一、選擇題
1.d
2.b
3.b
4.c
5.d
6.b
7.b
8.a
9.b
10.d
二、填空題
1.數(shù)據(jù)、函數(shù)
2.析構(gòu)
3.本類對象的引用
4.->
5.this指針
6.static
7.友元
8.類的構(gòu)造函數(shù)
9.成員初始化列表
10.對象成員
11.②⑩ 改正如下:
②double r;
⑩末尾加分號。
12.①A::num=num;?②return num;
13.?????????????????????????????????????????
①strcpy(c,ch);
②cout<<i<<","<<j<<","<<c<<endl;
14.int?Point::countP=0;
15.??j=i,t=a[i]
?
三、編程題
1.參考程序如下:
#include<iostream.h>
#include<math.h>
class cube
{
???????double x;
public:
???????cube(double xx)
???????{
??????????????x=xx;
???????}
???????double volume();
???????double?sarea();
??????
};
double?cube::volume()
{
???????return?pow(x,3);
}
double?cube::sarea()
{
???????return?pow(x,2)*6;
}
void main()
{
???????double a;
???????cout<<"請輸入棱長:";
???????cin>>a;
???????cube c(a);
???????cout<<"該正方體的體積為:"<<c.volume ()<<endl
??????????????<<"該正方體的表面積為:"<<c.sarea()<<endl;
}
2.參考程序如下:
#include<iostream.h>
class Time
{
???????int?hour;
???????int?minute;
???????int?second;
public:
???????int?sethour(int);
???????int?setminute(int);
???????int?setsecond(int);
???????int?gethour();
???????int?getminute();
???????int?getsecond();
???????void show12();
???????void show24();
};
int?Time::sethour(int?h)
{
???????if(h>=24||h<0)
??????????????return 0;?
???????else
???????{
??????????????hour=h;
??????????????return 1;
???????}
}
int?Time::setminute(int?m)
{
???????if(m>=60||m<0)
??????????????return 0;
???????else
???????{
??????????????minute=m;
??????????????return 1;
???????}
}
int?Time::setsecond(int?s)
{
???????if(s>=60||s<0)
??????????????return 0;
???????else
???????{
??????????????second=s;
??????????????return 1;
???????}
}
int?Time::gethour(){return hour;}
int?Time::getminute(){return minute;}
int?Time::getsecond(){return second;}
?
void Time::show12()
{
???????if(hour==12)
??????????????cout<<hour<<":"<<minute<<":"<<second<<"AM"<<endl;
???????else
??????????????cout<<hour%12<<":"<<minute<<":"<<second
??????????????????<<((hour<12&&hour>=0)?"AM":"PM")<<endl;
}
void Time::show24()
{
???????cout<<hour<<":"<<minute<<":"<<second<<endl;
}
?
void main()
{
???????int?h,m,s;
???????cin>>h>>m>>s;
???????Time t;
???????if(t.sethour(h)==0||t.setminute(m)==0||t.setsecond(s)==0)
???????{
??????????????cout<<"輸入時間錯誤!";
??????????????return;
???????}
???????t.show12();
???????t.show24();
?
}
?
來源:http://www1.lzcc.edu.cn/cplusplus/exercises/exercises08.htm
轉(zhuǎn)載于:https://www.cnblogs.com/gjianw217/p/3366104.html
總結(jié)
以上是生活随笔為你收集整理的C++程序员笔试复习概要(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Eclipse中JRE System L
- 下一篇: C++学习笔记--(1)