C++中的抽象類及動態類型轉換

抽象類與純虛函數

1. 抽象類

類太抽象以至於無法實例化就叫做抽象類(描述是不是絕了,類越往下派生肯定越具體,越往上肯定越抽象)

2. 抽象函數/純虛函數

2.1. 成員函數應出現在哪個繼承層次?

問題:Shape類層次中,getArea()函數放在哪個層次

選擇1:放哪兒都行:Shape中或子類中定義getArea()

選擇2:強制要求Shape子類必須實現getArea()

2.2. 抽象函數(abstract functions)要求子類實現它

virtual double getArea() = 0;  // 在Shape類中

Circle子類必須實現getArea()純虛函數才能實例化 

2.3. 包含抽象函數的類被稱爲抽象類

抽象類不能實例化(創建對象)

3. Abstract Class Example

 


動態類型轉換 

1. 爲何需要動態類型轉換 

void printObject(Shape& shape)

// shape是派生類對象的引用

{

  cout << "The area is "

       << shape.getArea() << endl;

  // 如果shape是Circle對象,就輸出半徑

  // 如果shape是Rectangle對象,就輸出寬高

}

 

 

如果你要修改函數,讓它顯示圓的半徑該怎麼辦?

2. Dynamic Casting Example

2.1. dynamic_cast 運算符

(1)     沿繼承層級向上、向下及側向轉換到類的指針和引用

(2)     轉指針:失敗返回nullptr

(3)     轉引用:失敗拋異常

2.2. 例子

先將Shape對象用dynamic_cast轉換爲派生類Circle對象

然後調用派生類中獨有的函數 

// A function for displaying a Shape object

void printObject(Shape &shape)

{

  cout << "The area is "

       << shape.getArea() << endl;

  Shape *p = &shape;

  Circle *c = dynamic_cast<Circle*>(p);

  // Circle& c = dynamic_cast<Circle&>(shape); 

  // 引用轉換失敗則拋出一個異常 std::bad_cast

  if (c != nullptr) // 轉換失敗則指針爲空

  {

    cout << "The radius is "

         << p1->getRadius() << endl;

    cout << "The diameter is "

         << p1->getDiameter() << endl;

  }

}

 


向上轉換和向下轉換

1. 向上/向下 轉型

1.1. upcasting : 將派生類類型指針賦值給基類類型指針

1.2. downcasting : 將基類類型指針賦值給派生類類型指針

 

 

Upcast

Downcast

computer = pc

pc = computer

computer = desktop

desktop = computer

pc = desktop

desktop = pc

2. 向上/向下 轉型 

2.1. 上轉可不使用dynamic_cast而隱式轉換

Shape* s = nullptr;

Circle *c = new Circle(2);

s = c; //OK,隱式上轉

 

2.2. Downcasting must be performed explicitly. (下轉必須顯式執行)

Shape* s = new Circle(1);

Circle *c = nullptr;

c = dynamic_cast <Circle*> (s); //顯式下轉

 

父上,子下

上轉隱,下轉顯

3. 基類對象和派生類對象的互操作

3.1. 對象內存佈局

Shape S;//基類對象

Circle C;//派生類對象

 

 

 

 

1可將派生類對象截斷,只使用繼承來的信息(意思是派生對象可以賦值給基類對象,截斷自己將繼承來的部分賦值給基類)

2但不能將基類對象加長,無中生有變出派生類對象(二基類對象不能賦值給派生類對象,因爲radius無從賦值)

那麼,下面四個語句的正確與否很顯而易見了:

①S = C;          (√)

②C = S;        (×)

③Shape &rS = C;(√)

④Circle &rC = S;     (×)

 

 

 

 

 

不恰當的記錄下:(保護屬性的數據或函數可被派生類成員訪問)

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