第五章 課後習題(P139-140)

習題
一、填空題
(1)C++的兩種聯編方式爲:  靜態  聯編  動態  聯編。
(2)C++支持兩種多態性,靜態聯編所支持的多態性被稱爲  編譯時的多態性  、動態聯編所支持的多態性被稱爲  運行時的多態性 
(3)重載函數在編譯時表現出多態性,就是  靜態   聯編;而虛函數則在運行時表現出多態性是  動態  聯編。
(4)爲了區分重載函數,把一個派生類中重定義基類的虛函數稱爲  覆蓋  
(5)如果派生類與基類的虛函數僅僅返回類型不同,其餘相同,則C++認爲是  使用不恰當的虛函數 
(6)在構造函數和析構函數中調用虛函數時,採用  靜態  聯編。
(7)純虛函數的定義是在虛函數定義的基礎上,再讓函數等於  0 
(8)對於包含有純虛函數的類被稱爲  抽象類 

二、選擇題(至少選一個,可以多選)

(1)用關鍵字( A )標記的函數被稱爲虛函數。
A. virtual                   B. private                    C. public                 D. protected
(2)在C++中,要實現動態聯編,必須使用( D )調用虛函數。
A. 類名                      B. 派生類指針               C. 對象名                 D. 基類指針
(3)下列函數中,可以作爲虛函數的是( BD )。
A. 普通函數                B. 非靜態成員函數        C. 構造函數             D. 析構函數
(4)在派生類中,重載一個虛函數時,要求函數名、參數的個數、參數的類型、參數的順序和函數的返回值( B )。
A. 不同                       B. 相同                         C. 相容                    D. 部分相同
(5)使用虛函數保證了在通過一個基類類型的指針(含引用)調用一個虛函數時,C++系統對該調用進行( A ),但是,在通過一個對象訪問一個虛函數時,使用( B )。
A. 動態聯編                B. 靜態聯編                   C. 動態編譯              D. 靜態編譯
(6)下面函數原型聲明中,(  B  )聲明的func()爲純虛函數。
A. void func()=0;                                            B. virtual void func()=0;
C. vitual void func();                                       D. virtual void func(){};
(7)若一個類中含有純虛函數,則該類稱爲(  C  )。
A. 基類                       B. 虛基類                       C. 抽象類                 D. 派生類
(8)假設Myclass爲抽象類,下列聲明( CD  )是錯誤的。
A. Myclass& func(int);                                     B. Myclass * pp;
C. int func(Myclass);                                        D. Myclass Obj;
(9)下面描述中,( BD  )是正確的。
A. 虛函數是沒有實現的函數                                B. 純虛函數的實現是在派生類中定義
C. 抽象類是隻有純虛函數的類                             D. 抽象類指針可以指向不同的派生類

三、判斷題

(1)抽象類中只能有一個純虛數。                                                                         ( 錯 )
(2)構造函數和析構函數都不能說明爲虛基數。                                                             ( 錯 )
(3)程序中可以說明抽象類的指針或引用。                                                                 ( 對 )
(4)一個類中的虛基數說明不僅對基類中的同名函數有影響,而且對它的派生類中的重定義的函數也有影響         ( 錯 )
(5)在構造函數和析構函數中調用虛函數時,採用動態聯編,即它們所調用的虛函數時是在派生類中重定義的虛函數 ( 錯 )
(6)因爲沒有爲純虛函數定義代碼,所以在構造函數和析構函數內均不可調用純虛函數。                         ( 對 )

四、簡答題

(1)什麼叫做多態性?在C++中是如何實現多態的?
答:多態性就是同一符號或名字在不同情況下具有不同解釋的現象,即是指同一個函數的多種形態。C++可以支持兩種多態性,編譯時的多態性和運行時的多態性。
多態性有兩種變現形式:一種是不同的對象在收到相同的消息時,產生不同的動作,主要通過虛函數來實現;另一種是同一對象收到相同的消息卻產生不同的函數調用,主要通過函數重載來實現。
(2)虛函數與一般重載函數有哪些區別?
答:虛函數與一般重載函數的區別,主要有以下幾點:
 重載函數只要求函數有相同的函數名,並且重載函數是在相同作用域中定義的名字相同的不同函數。而虛函數不僅要求函數名相同,而且要求函數的簽名、返回類型也相同。也就是說函數原型必須完全相同,而且虛函數特性必須是體現在基類和派生類的類層次結構中。
  重載函數可以是成員函數或友元函數,而虛函數只能是非靜態成員函數。
  構造函數可以重載,析構函數不能重載。正好相反,構造函數不能定義爲虛函數,析構函數能定義爲虛函數。
  重載函數的調用是以所傳遞參數序列的差別作爲調用不同函數的依據,而虛函數是根據對象的不同去調用不同類的虛函數。
 重載函數在編譯時表現出多態性,是靜態聯編;而虛函數則在運行時表現出多態性是動態聯編,因此說動態聯編是C++的精髓。
(3)什麼叫做抽象類?抽象類有何作用?抽象類的派生類是否一定要給出純虛函數的實現?
答:一個類可以說明多個純虛函數,對於包含有純虛函數的類被稱爲抽象。抽象類用來描述一組子類的共同的操作接口,它用作基類。抽象類的派生類不一定要給出純虛函數的實現。如果沒有在派生類中給出純虛函數的實現,則需在派生類中仍將它說明爲純虛函數,否則編譯器將給出錯誤信息。說明了純虛函數的派生類仍是抽象類。
(4)能否聲明虛析構函數?有何用途?
答:能聲明虛析構函數。如果一個類中定義了虛函數,析構函數也應說明爲虛函數。delete運算符和析構函數一起工作,當使用delete刪除一個對象時,delete隱含着對析構函數的一次調用,這樣保證了使用基類類型的指針能夠調用適當的析構函數針對不同的對象進行清除工作。

五、程序設計題
(1)使用虛函數編寫程序求球體和圓柱體的體積及表面積。由於球體和圓柱體都可以看作由圓繼承而來,所以可以定義圓類Circle作爲基類。在Circle類中定義一個數據成員radius和兩個虛函數area()和volume()。由Circle 類派生Sphere類和Column類。在派生類中對虛函數area()和volume()重新定義,分別求球體和圓柱體的體積及表面積。
#include <iostream>
#include <iomanip>
using std::fixed;
using std::setprecision;
using namespace std;
const double PI=3.14159265;
class Circle
{ public:
     Circle(double r) {radius=r;}
    virtual double area() {return 0.0;}
    virtual double volume() {return 0.0;}
  protected:
    double radius;
};
class Sphere:public Circle
{  public:
     Sphere(double r):Circle(r){ }
     double area() {return 4.0*PI*radius*radius;}
     double volume()
      { return 4.0/3.0*PI*radius*radius*radius;}
};
class Column:public Circle
{  public:
     Column(double r,double h):Circle(r){height=h;}
     double area()
       { return 2.0*PI*radius*(height+radius );}
     double volume()
       { return PI*radius*radius*height;}
     private:
       double height;
};
int main()
{
   Sphere s(3.0);
   Column c(4.0,5.0);
   cout <<fixed<<setprecision(2)<< "球的體積 = " << s.volume() << endl;
   cout << fixed<<setprecision(2)<<"球的表面積 = " << s.area() << endl;
   cout << fixed<<setprecision(2)<<"圓柱體的體積 = " << c.volume() << endl;
   cout <<fixed<<setprecision(2)<< "圓柱體的表面積 = " << c.area() << endl;
   return 0;
}
程序輸出結果如下:
(2)編寫一個程序,用於計算正方形、三角形和圓的面積及計算各類形狀的總面積。
#include<iostream>
#include<iomanip>
using std::fixed;
using std::setprecision;
const double PI=3.1415;
using namespace std;
class square
{
public:
    square(float l){length=l;}
    virtual float area(){return length*length;}
private:
    float length;
};
class triangle
{
public:
    triangle(float b,float h){base=b;height=h;}
    virtual float area(){return base*height/2.0;}
private:
    float base,height;
};
class Circle
{
public:
    Circle(double r){radius=r;}
    virtual double area(){return PI*radius*radius;}
private:
    double radius;
};
int main()
{
    square s(6.0);
    triangle t(3.0,4.0);
    Circle c(5.0);
    cout<<fixed<<setprecision(2)<<"正方形的面積="<<s.area()<<endl;
    cout<<fixed<<setprecision(2)<<"三角形的面積="<<t.area()<<endl;
    cout<<fixed<<setprecision(2)<<"圓的表面積="<<c.area()<<endl;
    cout<<fixed<<setprecision(2)<<"各類形狀的總面積="<<s.area()+c.area()+t.area()<<endl;
    return 0;
}
程序輸出結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章