在C++中随處可見封裝,繼承,多态。
多态的實作,是基于虛函數的繼承,虛函數則是基于虛函數表和虛函數表指針。
用一個示例介紹虛函數表指針通路虛函數,更易于友善了解虛函數,程式中也有注釋
// virtual-table.cpp
#include <iostream>
using namespace std;
class A {
public:
A() {
cout << __func__ << endl;
}
virtual void fun() {
cout << "A : " << __func__ << endl;
};
virtual void bar() {
cout << "A : " << __func__ << endl;
};
};
class B : public A {
public:
B() : A() {
cout << __func__ << endl;
}
void fun() {
cout << "B : " << __func__ << endl;
}
void bar() {
cout << "B : " << __func__ << endl;
}
};
int main (int argc, char *argv[])
{
typedef void (*pfun) (void);
int bits = sizeof(int *);
B b;
B b1;
cout << "-------- 虛函數表 -----------" << endl;
// 虛表位址存在于每個執行個體對象的首位址處
// 虛函數表位址是同一個位址,說明虛表隻屬于該類
// 不屬于該類的執行個體子對象
cout << *(int *)*(int *)&b << endl;
cout << *(int *)*(int *)&b1 << endl;
pfun fun = NULL;
pfun fun1 = NULL;
cout << "----- 利用虛表調用函數 ------" << endl;
fun = (pfun)*((int *)*(int *)&b);
fun();
if (8 == bits) {
fun = (pfun)*((int *)*(int *)&b + 2);
}
else if (4 == bits) {
fun = (pfun)*((int *)*(int *)&b + 1);
}
fun();
fun1 = (pfun)*((int *)*(int *)&b);
fun1();
if (8 == bits) {
fun1 = (pfun)*((int *)*(int *)&b + 2);
}
else if (4 == bits) {
fun1 = (pfun)*((int *)*(int *)&b + 1);
}
fun1();
// 多态
cout << "---------- 指針 -------------" << endl;
A *a = new B;
a->fun();
cout << "---------- 引用 -------------" << endl;
A &a1 = b;
a1.bar();
return 0;
}
編譯,運作
[email protected] $ g++ virtual-table.cpp
[email protected] $ ./a.out
A
B
A
B
-------- 虛函數表 -----------
4197940
4197940
----- 利用虛表調用函數 ------
B : fun
B : bar
B : fun
B : bar
---------- 指針 -------------
A
B
B : fun
---------- 引用 -------------
B : bar