c++::詳解虛表
【虛表的建立】:
1)基類(虛表):按照虛擬函式在基類中出現的先後次序進行一次逐個填寫虛表地址。
2)派生類(虛表):
A、先要知道基類虛表的格式
B、派生類對基類中那些虛擬函式進行重寫,如果重寫了,會將虛表中相同偏移位置的函式的地址進行重寫
C、再將最後四個位元組寫為0
注意:
1、 不同物件的虛表地址相同
2、 基類型別的指標指向派生類物件,要呼叫派生類重寫的函式時,無法呼叫
【不同繼承方式下不同情況的虛表】:
(分別從繼承方式,有無重寫和是否是虛擬繼承來進行分析)2.1單繼承的無重寫的虛表
1)說明:程式的結果:
A:基類的列印自己的,派生類的也列印自己的
B:基類大小:如果有成員的話,就是成員加頭四個位元組(指向虛表的指標)派生類大小;如果有成員的話,就是成員加基類加指向虛表的指標
2)舉例程式碼:
3)程式的執行結果圖:#include<iostream> using namespace std; class Base { public: Base() { b=10; } virtual void fun0() { cout<<"Base::fun0()"<<endl; } virtual void fun1() { cout<<"Base::fun1()"<<endl; } virtual void fun2() { cout<<"Base::fun2()"<<endl; } int b; }; class Derived:public Base { public: Derived() {} virtual void fun3() { cout<<"Derived::fun3()"<<endl; } virtual void fun4() { cout<<"Derived::fun4()"<<endl; } virtual void fun5() { cout<<"Derived::fun5()"<<endl; } int d; }; typedef void (*vpf)(); void Printvpf() { Base b; Derived d; cout<<"Base::vpf"<<endl; vpf* n = (vpf*)*(int *)(&b); while(*n) { (*n)(); n++; } cout<<"Derived::vpf"<<endl; vpf* pn = (vpf*)*(int *)(&d); while(*pn) { (*pn)(); pn++; } cout<<sizeof(Base)<<endl; cout<<sizeof(Derived)<<endl; } int main() { Printvpf(); return 0; }
2.2單繼承的有重寫的虛表
1)說明:程式的結果:
基類依然列印自己的,派生類將基類對應偏移位置的覆蓋掉
2)舉例程式碼:
3)執行程式結果#include<iostream> using namespace std; class Base { public: Base() { b=10; } virtual void fun0() { cout<<"Base::fun0()"<<endl; } virtual void fun1() { cout<<"Base::fun1()"<<endl; } virtual void fun2() { cout<<"Base::fun2()"<<endl; } int b; }; class Derived:public Base { public: Derived() {d = 10;} virtual void fun0() { cout<<"Derived::fun0()"<<endl; } virtual void fun1() { cout<<"Derived::fun1()"<<endl; } virtual void fun5() { cout<<"Derived::fun5()"<<endl; } int d; }; typedef void (*vpf)(); void Printvpf() { Base b; Derived d; cout<<"Base::vpf"<<endl; vpf* n = (vpf*)*(int *)(&b); while(*n) { (*n)(); n++; } cout<<"Derived::vpf"<<endl; vpf* pn = (vpf*)*(int *)(&d); while(*pn) { (*pn)(); pn++; } cout<<sizeof(Base)<<endl; cout<<sizeof(Derived)<<endl; } int main() { Printvpf(); return 0; }
1)程式執行結果說明:
A:基類列印自己的,派生類只打印自己的,並不會列印基類的
B:基類大小:不變
派生類大小:要加一個偏移量,所以多八個位元組
依次是:指向派生類的虛表指標,偏移量,派生類的資料成員,
指向基類的虛表指標,基類的資料成員
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class Derived:virtual public Base
{
public:
Derived()
{d = 20;}
virtual void fun3()
{
cout<<"Derived::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Derived::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Derived::fun5()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
Derived d;
//Base* p = &d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"Derived::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&d);
while(*pn)
{
(*pn)();
pn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式執行結果:
4)物件模型分析:
2.4單繼承的虛擬繼承的有重寫的虛表
1)程式結果分析:
A:基類列印的不變,派生類將重寫的不列印,只打印自己的
B:基類大小:不變
派生類的大小:和無重寫的幾乎一樣,不過多了一個用於區分物件的0
這個0加在了派生類資料成員和指向基類虛表的指標之間,
這就是多出來的四個位元組
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class Derived:virtual public Base
{
public:
Derived()
{d = 20;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Derived::fun1()"<<endl;
}
virtual void fun5()
{
cout<<"Derived::fun5()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
Derived d;
//Base* p = &d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"Derived::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&d);
while(*pn)
{
(*pn)();
pn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式碼執行結果:
4)物件模型分析
2.5多繼承的無重寫的虛表
1)程式執行結果說明:
A:基類1:列印自己的
B: 基類2:列印自己的
C:派生類:列印基類一,列印自己的
D:大小:基類大小不變,派生類大小是基類一加基類2加自己的資料成員大小
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun6()
{
cout<<"Derived::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*((int *)(&d)+2);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式碼執行結果
4)物件模型說明
2.6多繼承的有重寫的虛表
1)程式執行結果說明:
A: 執行結果:派生類覆蓋了基類的,其他不變
B: 大小:同上
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Derived::fun1()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
4)物件模型解析
這個我就不做過多的分析了。
2.8多繼承的虛擬繼承的無重寫的虛表(虛擬繼承一個基類)
1)程式執行結果說明:
A:基類列印:基類列印自己的
B:大小:多了偏移量,多了四個位元組
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun6()
{
cout<<"Derived::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式碼執行結果:
4)
2.9多繼承的虛擬繼承的無重寫的虛表(虛擬繼承所有的基類)
1)程式執行結果分析
A:基類列印:基類列印自己的,派生類只打印自己的
B:大小:多了偏移量,多了八個位元組
2)舉例程式碼
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,virtual public Base2
{
public:
Derived()
{d = 30;}
virtual void fun6()
{
cout<<"Derived::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式執行結果
4)物件模型分析
2.10多繼承的虛擬繼承的有重寫的虛表(虛擬繼承一個基類)
1)程式執行結果說明 A:基類不變,派生類重寫的基類一未影響,二會覆蓋 2)舉例程式碼:#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun4()
{
cout<<"Derived::fun4()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式執行結果
4)物件模型說明
2.11多繼承的虛擬繼承的有重寫的虛表(虛擬繼承所有的基類)
1)程式執行結果說明:
A:基類不變,派生類重寫的不列印,只打印自己的
B:大小:重寫的話,重寫幾個就多幾個位元組,多了一個用於區分的零在B1和D之間
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,virtual public Base2
{
public:
Derived()
{d = 30;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式執行結果
2.12無重寫普通的菱形繼承
1)程式執行結果分析:
A:不過加了虛擬函式,這時D記憶體結果是順序繼承:B,C1,C2,D,
(但是在C1和C2之間多了一個地址和一個數據。我的編譯器是這樣)
B: D執行結果:打印出基類B,基類C1,D
C:執行結果的大小:28
2)舉例程式碼:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class C1:public Base
{
public:
C1()
{
c1=20;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
int c1;
};
class C2:public Base
{
public:
C2()
{
c2=30;
}
virtual void fun6()
{
cout<<"C2::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"C2::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"C2::fun8()"<<endl;
}
int c2;
};
class Derived:public C1,public C2
{
public:
Derived()
{
d = 40;
}
virtual void fun9()
{
cout<<"Derived::fun9()"<<endl;
}
virtual void fun10()
{
cout<<"Derived::fun10()"<<endl;
}
virtual void fun11()
{
cout<<"Derived::fun11()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
C1 c1;
C2 c2;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"C1::vpf"<<endl;
vpf* pn1 = (vpf*)*(int *)(&c1);
while(*pn1)
{
(*pn1)();
pn1++;
}
cout<<"C2::vpf"<<endl;
vpf* pn2 = (vpf*)*(int *)(&c2);
while(*pn2)
{
(*pn2)();
pn2++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(C1)<<endl;
cout<<sizeof(C2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式碼執行結果
2.13無重寫(只有一個直接基類的此處為C1)普通的菱形繼承
1)程式執行結果分析
A:D 的列印結果:列印C1,列印D
當然C1的大小多了八個位元組
B:執行結果的大小36
2)舉例程式碼
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class C1:virtual public Base
{
public:
C1()
{
c1=20;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
int c1;
};
class C2:public Base
{
public:
C2()
{
c2=30;
}
virtual void fun6()
{
cout<<"C2::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"C2::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"C2::fun8()"<<endl;
}
int c2;
};
class Derived:public C1,public C2
{
public:
Derived()
{
d = 40;
}
virtual void fun9()
{
cout<<"Derived::fun9()"<<endl;
}
virtual void fun10()
{
cout<<"Derived::fun10()"<<endl;
}
virtual void fun11()
{
cout<<"Derived::fun11()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
C1 c1;
C2 c2;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"C1::vpf"<<endl;
vpf* pn1 = (vpf*)*(int *)(&c1);
while(*pn1)
{
(*pn1)();
pn1++;
}
cout<<"C2::vpf"<<endl;
vpf* pn2 = (vpf*)*(int *)(&c2);
while(*pn2)
{
(*pn2)();
pn2++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(C1)<<endl;
cout<<sizeof(C2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式執行結果
2.13無重寫(所有的直接基類都虛擬繼承)普通的菱形繼承
1)程式執行結果分析
A:和上面的幾乎一樣,不同的是C2必然多了八個位元組
2)舉例程式碼;
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class C1:virtual public Base
{
public:
C1()
{
c1=20;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
int c1;
};
class C2:virtual public Base
{
public:
C2()
{
c2=30;
}
virtual void fun6()
{
cout<<"C2::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"C2::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"C2::fun8()"<<endl;
}
int c2;
};
class Derived:public C1,public C2
{
public:
Derived()
{
d = 40;
}
virtual void fun9()
{
cout<<"Derived::fun9()"<<endl;
}
virtual void fun10()
{
cout<<"Derived::fun10()"<<endl;
}
virtual void fun11()
{
cout<<"Derived::fun11()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
C1 c1;
C2 c2;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"C1::vpf"<<endl;
vpf* pn1 = (vpf*)*(int *)(&c1);
while(*pn1)
{
(*pn1)();
pn1++;
}
cout<<"C2::vpf"<<endl;
vpf* pn2 = (vpf*)*(int *)(&c2);
while(*pn2)
{
(*pn2)();
pn2++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(C1)<<endl;
cout<<sizeof(C2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程式執行結果
最後要說明的:還有一些情況類似於上面的,我就不一一說明了,我寫的都是比較經典的情況,希望能對大家有所幫助!