《《C++面向對象程序設計》期末考試試題》由會員分享,可在線閱讀,更多相關《《C++面向對象程序設計》期末考試試題(6頁珍藏版)》請在裝配圖網上搜索。
1、《C++面向對象程序設計》考試試題
本試卷滿分100分;
請將答案寫在答題紙上,寫明題號,不必抄題,字跡工整、清晰;
請在答題紙和試題紙上都寫上你的班級,學號和姓名,交卷時請將試題紙、答題紙和草紙
一并交上來。
一、 單選題(共10分,每題1分)
1. C++中解決命名沖突的機制是:D
(A) 虛基類 (B) 虛函數(shù) (C) 函數(shù)重載 (D) 名字空間
2. 若類A的一個對象所占的內存空間中包含虛函數(shù)表的入口地址,則: C
(A) 類A不能有靜態(tài)數(shù)據成員 (B) 類A中公有的成員函數(shù)一定是虛的
(C) 類A中至少有一個
2、成員函數(shù)是虛的 (D) 類A的析構函數(shù)一定是虛的
3.任意一個類,析構函數(shù)的個數(shù)最多是:B
(A) 不限個數(shù) (B) 1 (C) 2 (D) 3
4. 下列關于this指針的說法,哪個是正確的: D
(A) this指針一定指向常量型數(shù)據 (B) this指向的數(shù)據不可更改
(C) 靜態(tài)成員函數(shù)中也可以訪問this指針 (D) this指針本身可直接作為成員函數(shù)的返回值
5.在類定義中,為說明成員的訪問權限,private, protected, public 可以出現(xiàn)次數(shù)為:A
(A)次數(shù)沒有具體限定
3、 (B) 每種至多一次
(C) public 至少一次 (D) 每種至少一次
6.下面哪種定義方式是正確的,并且使得p可以作為函數(shù)void f( A* const pp);的實參:A
(A) A * p = new A; (B) A a; A* p = a;
(C) const A* p = new A; (D) A a; const A* p = a;
7. obj是類A的一個對象,執(zhí)行語句 const A& aA= obj; ,則下列說法正確的是: C
(A) 類A的拷貝構
4、造函數(shù)會被調用 (B) 類A的賦值函數(shù)會被調用
(C) &aA的值就是 &obj (D) 語句obj.f( );等價于語句aA.f( );
8.下面關于訪問類A的私有數(shù)據成員的說法,錯誤的是: C
(A) 類A的友元函數(shù)可以訪問類A的私有成員。
(B) 類A的友元類中的非靜態(tài)成員函數(shù)可以訪問類A的私有成員。
(C) 類A的嵌套類中的非靜態(tài)成員函數(shù)可以訪問類A的私有成員。
(D) 類A中的非靜態(tài)成員函數(shù)可以訪問類A的私有成員。
9.類A中有唯一的一個成員函數(shù)f,且f是公有的靜態(tài)或非靜態(tài)成員函數(shù),對于類A的一個對象a,執(zhí)行語句 a.f(100)
5、;成功,那么f 的函數(shù)原型不可以是:B
(A) A& f( int, int=50 ); (B) void f(int& ) ;
(C) const A * f(const int ); (D) A f( const int&);
10. 下面關于類的成員函數(shù)描述不正確的是:A
(A) 靜態(tài)成員函數(shù)內可以直接訪問類的非靜態(tài)成員數(shù)據
(B) 靜態(tài)成員函數(shù)內可以直接訪問類的靜態(tài)成員數(shù)據
(C) 非靜態(tài)成員函數(shù)可以直接訪問類的非靜態(tài)成員數(shù)據
(D) 非靜態(tài)成員函數(shù)可以直接訪問類的靜態(tài)成員數(shù)據(全局成員)
二、判斷正誤,對于你認為
6、錯誤的論述,說明原因或舉出反例。(每題2分,共20分)
1. 重載流操作符<<和>> 時,如果第一個參數(shù)的類型為ostream 和istream,那么這個重載函數(shù)既可以用于標準輸入輸出流,也可以用于文件流上。
對,ostream 和istream是標準輸入輸出流、文件流、字符串流的基類
2. 在同一個類中,可以定義重載的成員函數(shù) void f(int);和virtual void f(int); 。
錯,這屬于重復定義
3. 抽象類不會產生實例,所以不需要有構造函數(shù)。
錯,被派生時需要它的構造函數(shù)
4. 類A有一個非靜態(tài)的成員函數(shù)f,其函數(shù)原型是:void A::f( ) con
7、st,則該函數(shù)被調用時,一定是通過類A或類A的某后裔類的一個用const修飾符說明的常量對象調用的。
錯,常函數(shù)可以由變量對象或常量對象調用
5. 異常必須在其產生的當前函數(shù)中捕獲,而不能在外層函數(shù)中捕獲該異常。
錯,可以在外層捕獲,并且這是最常見的用法
6. 只要程序中沒有A a1 = a2; 和A a1(a2); 形式的代碼,類A的拷貝構造函數(shù)就不會被調用。
錯,參數(shù)傳遞或函數(shù)返回時也調用拷貝構造函數(shù)
7. 在protected繼承方式下,派生類對象的指針不能直接轉換成指向基類對象的指針。
對,否則基類中的公有成員由不可見變?yōu)榭梢姡瑱嘞薇环糯?
8. 若靜態(tài)成員函數(shù)中調用
8、了一個函數(shù)f,那么f 一定不是虛函數(shù)。
對,靜態(tài)成員函數(shù)不能是虛函數(shù),因為虛函數(shù)入口需要在保存在對象中的虛函數(shù)
表中,而靜態(tài)成員函數(shù)不屬于對象。
9. 若要實例化一個含有引用型數(shù)據成員的類,那么只能使用構造函數(shù)初始化列表來初始化該數(shù)據成員。
對,沒有別的辦法
10. 構造函數(shù)的函數(shù)體中,不能使用return語句;但在實現(xiàn)該類的自動類型轉化函數(shù)時,必須有return 語句。
對
三、回答下列各題(每題4分,共20分)
1. 舉例說明static關鍵字的用法和相應目的(至少3種)。
f(){ static int a;…} 函數(shù)體內的靜態(tài)變量,每次調用該函數(shù)時值保持不變
s
9、tatic int a; 全局的靜態(tài)變量,約束作用域為所在文件
class A {static int a;…}; A的靜態(tài)成員,類似全局變量,需用A::a訪問
2. 舉例說明類的數(shù)據成員在哪些情況下必須在初始化列表中進行初始化(至少3種)。
基類不提供無參的構造函數(shù)
成員對象不提供無參的構造函數(shù)
有常量成員或引用成員
3. 舉例說明虛擬繼承的作用和目的。
虛擬繼承的目的是使基類在派生類中只保留一個副本
從而避免二義性
4. 舉例說明成員函數(shù)A& f( ) const;和成員函數(shù)A& f( ); 的區(qū)別。
A& f( ) const是常函數(shù),隱含的this指針是常指針,因此
10、在f中不能修改對象成員的值。
舉例略
5. 有類A的對象a,任意給出一種解決方案,使得程序支持下面的表達式:
a=10+a;
class A {
A(int); //轉換構造函數(shù)
friend const A operator+(const A,const A); //重載+
};
四、指出下列程序代碼中存在的錯誤或不足,說明原因。(每題5分,共10分)
1.
#include
class A {
public:
virtual ~A( ) { }
virtual void f( )
{ cout<<"A:
11、:f( )"<f( );
p->g( );
p->k( );
del
12、ete p;
}
答:函數(shù)k在A中沒有定義,執(zhí)行p->k( );時要根據p的類型在A中查k的信息
2.
#include
#include
class A;
class B:public A {
public:
B(const char* info){
m_buf=new char[256];
strcpy(m_buf,info); }
~B( ) { delete[] m_buf; }
virtual void output( ) { cout << m_buf; }
13、private:
char * m_buf; };
class A {
public:
~A( ) { }
virtual void output( ) { }
};
void main()
{
A*pa = new B("hello!") ;
pa->output( );
delete pa;
}
答:A的析構函數(shù)應定義為虛函數(shù),否則B的析構函數(shù)不會被調用,m_buf也不會被釋放
五、寫出下面程序的運行結果(每題5分,共10分)
1.
#include
class A {
public
14、:
A( ):count(1) {}
virtual ~A( ) {}
virtual A* Copy( ) const = 0;
virtual void Out( ) const = 0;
protected:
int count;
};
class B:public A {
public:
~B( ) { --count; Out( ); }
virtual A* Copy( ) const {
B *p = new B(*this);
++p->count;
ret
15、urn p;
}
virtual void Out( ) const
{ cout << count << endl; }
};
void main( )
{
{
B b;
A* a1=&b;
a1->Out( );
a1 = a1->Copy( );
a1->Out( );
delete a1;
}
}
答:
1
2
1
0
--------------------
2.
#include
class A {
public:
A(int n):num(n)
16、 { Out( ); }
A(const A& rhs):num(rhs.num) {Out( );}
void Out( ) {cout<
17、 B b2(b1);
b2.Out();
}
答:
8
1
8
1
8
8
-------------
六、閱讀下面兩個類的定義和部分實現(xiàn)代碼,完成3個問題。(共10分)
#include
class A {
public:
A(int n):value(n) { }
void Display( ) const
{cout<<"Value = "<
18、 n);
void Display( ) const
{ aA.Display(); }
private:
A aA;
};
int main( )
{
B b1(1);
b1.Display( );
B b2(2);
b2. Display( );
return 0;
}
1. [3分]實現(xiàn)類B的構造函數(shù),使得程序的輸出為:
Value=1
Value=2
答:B(int n):aA(n)
2.[3分]若main函數(shù)中增加了語句B b3(b1); 針對本例,說明是否有必要以公有方式自定義并實現(xiàn)類B的拷貝構造函數(shù),為什么
19、?
答:不需要,因為類B及基類A中不存在引用或指針成員,使用默認的拷貝構造函數(shù)就可以。
3. [4分]在不改動類A和main函數(shù)的前提下,以繼承的方式重新定義并實現(xiàn)類B,使得程序的輸出結果不變。
答:
class B:public A {
public:
B(int n):A(n);
void Display( ) const
{ A::Display(); }
};
七、(共20分,每問題10分) 某程序員為了靈活地對各種的給定的曲線函數(shù)f(x)畫出其曲線圖形,設計并部分實現(xiàn)了一個曲線類curve,該類的成員數(shù)據中,count代表坐標點的個數(shù),pxs代表的數(shù)組
20、存放這些坐標點的橫坐標,pys代表的數(shù)組存放利用f(x)計算得到的這些坐標點的縱坐標。由于不同曲線的計算公式f(x)是不同的,該程序員希望曲線函數(shù)的種類可以通過繼承curve類的方式任意增加,增加一個新的f(x)時不改變curve類中的內容,也不改變利用curve類進行圖形繪制的算法。已部分完成的curve類定義和實現(xiàn)如下:
class curve {
public:
void setPxs( ) {/*把獲取的橫坐標數(shù)據存放在pxs代表的數(shù)組中,并為count置值*/ }
double* getPxs( ) const { return pxs;}
int getCoun
21、t( ) const { return count;}
double* getPys( ) const ;
private:
double* pxs;
double* pys;
int count
};
1、請按照該程序員的設計意圖給出成員函數(shù)getPys的完整實現(xiàn)。實現(xiàn)過程中,可以為curve類增加其它成員??梢约僭OsetPxs函數(shù)已經完整實現(xiàn),不需要考慮曲線的繪制和顯示。
答:
class curve {
public:
void setPxs( ) {/*把獲取的橫坐標數(shù)據存放在pxs代表的數(shù)組中,并為count置值*/ }
double* get
22、Pxs( ) const { return pxs;}
int getCount( ) const { return count;}
double* getPys( ) const ;
virtual double f(double)=0;
private:
double* pxs;
double* pys;
int count
};
double* curve::getPys( ) const
{
if(pys==NULL) pys=new double[count];
for(int i=0;i