1. 程式人生 > >C++學習之對多型的理解

C++學習之對多型的理解

最近學習C++多型及子類記憶體結構,有一些理解與看法,記錄下來

1.多型產生,虛擬函式,虛擬函式指標,虛擬函式表

這一部分不詳細描述,個人參考的書籍是Siddhartha Rao的<21天學通C++>的第11章:多型

瞭解了編譯器利用虛擬函式表與物件的虛擬函式指標來實現多型的機制

覺得比較好的文章就記在下面

【轉】:https://blog.csdn.net/jiangnanyouzi/article/details/3720807

2.自己的一些思考

Siddhartha Rao:在函式宣告中, virtual 意味著當基類指標指向派生物件時,通過它可呼叫派生類的相應函式

實際上不管有沒有出現virtual關鍵字,基類指標指向子類物件時都發生了一次隱式的強轉,即是說基類指標變數的值仍然與子類物件地址的值相同(子類物件第一個位元組的地址編號),但是偏移量不同。

所以在沒有virtual關鍵字的時候經過隱式強轉,基類指標變數實際指向的是一個基類的物件例項,那麼呼叫對應的方法等同於呼叫基類例項的方法

然而在有virtual關鍵字的時候也要經過隱式強轉,由於編譯器會給子類物件分配一個虛擬函式表指標,雖然基類指標指向的是一個基類物件例項,但是虛擬函式指標所指向的虛擬函式表中的函式卻是子類的函式,實現了基類指標呼叫派生類函式

自己驗證的程式碼如下:

[email protected]
:/lianxi/lianxi_c++/duotai# g++ 11.1\ InvokingSwimUsingFishPtr.cpp [email protected]:/lianxi/lianxi_c++/duotai# ./a.out Tuna swims! lets see InputFish->Swim() Fish swims! lets see p->Swim() Tuna swims! [email protected]:/lianxi/lianxi_c++/duotai#
  1 #include <iostream>
  2 #include <stdio.h>
  3 
  4 using namespace std;
  5 
  6 class Fish
  7 {
  8 public:
  9    void Swim()
 10    {
 11       cout << "Fish swims!" << endl;
 12    }
 13 };
 14 
 15 class Tuna:public Fish
 16 {
 17 public:
 18    void Swim()
 19    {
 20       cout << "Tuna swims!" << endl;
 21    }
 22 };
 23 
 24 void MakeFishSwim(Fish* InputFish)
 25 {
 26    printf("lets see InputFish->Swim()\n");
 27    InputFish->Swim();//Fish swims!
 28    putchar(10);
 29    printf("lets see p->Swim()\n");
 30    Tuna* p = NULL;
 31    p = (Tuna*)(InputFish);
 32    p->Swim();//Tuna swims!
 33    return;
 34 }
 35 
 36 int main() 
 37 {  
 38    Tuna myDinner;
 39    
 40    myDinner.Swim();
 41    
 42    MakeFishSwim(&myDinner);
 43    
 44    return 0;
 45 }