這一篇介紹一下 c++ 物件導向三大特徵之一的多型(之前面試某大廠的實習生被問到多型,後來又了解到一些設計模式,才體會到多型的強大,在這裡把對多型的一點點淺顯認識總結一下)
虛表
class
test};
cout <<
sizeof
(test)
<< endl;
test* p =
new test;
p->
vfunc()
;// 將類指標p強轉為long long指標,訪問前8byte(long long*每次操作8byte)獲取到虛表指標,再將虛表指標轉為long long指標,訪問前8byte獲取到函式指標,將函式指標強轉為void(*)()型別(類中的虛函式型別),即可呼叫函式
reinterpret_cast
<
void(*
)()>
(reinterpret_cast
<
long
long
*>(*
reinterpret_cast
<
long
long
*>
(p))[0
])()
;// 將上面的函式指標下移8byte獲得虛表的尾值0
cout <<
reinterpret_cast
<
long
long
*>(*
reinterpret_cast
<
long
long
*>
(p))[1
]<< endl;
// 執行結果(64bit目標平台下):
// 8
// test virtual function
// test virtual function
// 0
虛函式
class
test};
test()
.func()
;// 執行結果:virtual function ,這是通過臨時變數呼叫的,後面再詳細介紹一下臨時變數
// *****= 一般多型的實現 *****=
class
testa
virtual
~testa()
};class
test
:public testa
~test()
};testa* t =
new test;
// 父類指標指向子類空間(多型的實現)
t->
vfunc()
;// 執行結果:test virtual function,父類指標呼叫子類函式(多型的實現)
delete t;
// *****= 協變的情況 *****=
class
testa
virtual
~testa()
};class
test
:public testa
~test()
};testa* t =
new test;
// 父類指標指向子類空間(多型的實現)
t->
vfunc()
;// 執行結果:test virtual function,父類指標呼叫子類函式(多型的實現)
delete t;
class
testa
virtual
~testa()
};class
testb
:public testa
~testb()
};class
test
:public testb
~test()
};testb* t =
new test;
t->
vfunc()
;delete t;
// 執行結果: test virtual function
// test dtor
// testb dtor
// testa dtor
// 1. class testb 的 vfunc() 函式前面沒有加 virtual 但是它的子類依然可以重寫,說明class testb 的 vfunc() 函式重寫了 class testa 的 vfunc() 函式後自己預設就是虛函式了(前面的 virtual 可寫可不寫了)
// 2. 析構函式寫成虛函式後釋放子類的空間時,子類的析構函式執行後還會執行父類的析構函式,避免了記憶體洩漏
純虛函式
class
testa};
class
test
:public testa
~test()
};test* p =
new test;
p->
vfunc()
;// 解釋在虛表**的注釋處
reinterpret_cast
<
void(*
)()>
(reinterpret_cast
<
long
long
*>(*
reinterpret_cast
<
long
long
*>
(p))[0
])()
;// 執行結果:
// test virtual function
// test virtual function
虛析構
如果未特殊說明,以上測試均是在win10 vs2017 64bit編譯器下進行的
C 虛函式與多型
1.1 虛函式概念 1.定義 在乙個類的成員函式前面加上virtual關鍵字,則該函式就稱為虛函式。2.如果乙個函式不是類的成員函式,則該函式不能定義為虛函式。即就是類外面不能使用virtual關鍵字 1.2 純虛函式與抽象類 1.純虛函式 在虛函式的後面加上 0 virtual void disp...
c 多型與虛函式
多型按字面的意思就是多種形態。當類之間存在層次結構,並且類之間是通過繼承關聯時,就會用到多型。c 多型意味著呼叫成員函式時,會根據呼叫函式的物件的型別來執行不同的函式。下面的例項中,基類 shape 被派生為兩個類,如下所示 include using namespace std class sha...
虛函式與多型 C
引用和指標的靜態型別 編譯時可知的引用型別或指標型別 和動態型別 指標或引用所繫結的物件的型別,執行時獲知 可以不同。因此,可以用基類的指標或引用指向派生類的物件,再通過基類的指標或引用來呼叫虛函式,所執行的虛函式是引用或指標所指向的物件所屬型別定義的版本。c 函式預設不使用動態繫結,除非滿足兩個條...