C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现(六)
且是定义成全局的:
?
1 void __stdcall base1_fun1(CBase1* that)
2 {
3 ? ? std::cout << "base1_fun1()" << std::endl;
4 }
?
?
? ? 3. 有虚函数覆盖的Base3
?
? ? ? ? ?虚函数覆盖在这里并不能体现出来, 要在构造对象初始化的时候才会体现, 所以: base3其实和Base1是一样的.
?
复制代码
?1 struct CBase3
?2 {
?3 ? ? void** __vfptr;
?4 ? ? int base3_1;
?5 };
?6?
?7 struct CBase3_VFTable
?8 {
?9 ? ? void(__stdcall* base3_fun1)(CBase3* that);
10 };
复制代码
?
?
Base3的成员函数:
?
1 void __stdcall base3_fun1(CBase1* that)
2 {
3 ? ? std::cout << "base3_fun1()" << std::endl;
4 }
?
?
? ? ?4. 定义继承类CDerive1
?
? ? ? ? ?相对前面几个类来说, 这个类要显得稍微复杂一些了, 因为包含了前面几个类的内容:
?
复制代码
1 struct CDerive1
2 {
3 ? ? CBase1 base1;
4 ? ? CBase3 base3;
5 ? ? CBase2 base2;
6?
7 ? ? int derive1_1;
8 };
复制代码
?
?
? ? ? 特别注意: CBase123的顺序不能错!
?
? ? ? 另外: 由于Derive1本身还有虚函数表, 而且所以项是加到第一个虚函数表(CBase1)的后面的, 所以此时的CBase1::__vfptr不应该单单指向CBase1_VFTable, 而应该指向下面这个包含Derive1类虚函数表的结构体才行:
?
1 struct CBase1_CDerive1_VFTable
2 {
3 ? ? void (__stdcall* base1_fun1)(CBase1* that);
4 ? ? void(__stdcall* derive1_fun1)(CDerive1* that);
5 };
?
?
? ? ? ?因为CDerive1覆盖了CBase3的base3_fun1()函数, 所以不能直接用Base3的那个表:
?
1 struct CBase3_CDerive1_VFTable
2 {
3 ? ? void(__stdcall* base3_fun1)(CDerive1* that);
4 };
?
?
? ? ? Derive1覆盖Base3::base3_fun1()的函数以及自身定义的derive1_fun1()函数:
?
复制代码
1 void __stdcall base3_derive1_fun1(CDerive1* that)
2 {
3 ? ? std::cout << "base3_derive1_fun1()" << std::endl;
4 }
5?
6 void __stdcall derive1_fun1(CDerive1* that)
7 {
8 ? ? std::cout << "derive1_fun1()" << std::endl;
9 }
复制代码
?
?
? ? ?5. 构造各类的全局虚函数表
?
? ? ? ? ? ?由于没有了编译器的帮忙, 在定义一个类对象时, 所有的初始化工作都只能由我们自己来完成了!
?
? ? ? ? ? ?首先构造全局的, 被同一个类共同使用的虚函数表!
?
复制代码
1 ? ? // CBase1 的虚函数表
2 ? ? CBase1_VFTable __vftable_base1;
3 ? ? __vftable_base1.base1_fun1 = base1_fun1;
4?
5 ? ? // CBase3 的虚函数表
6 ? ? CBase3_VFTable __vftable_base3;
7 ? ? __vftable_base3.base3_fun1 = base3_fun1;
复制代码
?
?
? ? ? ? ?然后构造CDerive1和CBase1共同使用的虚函数表:
?
1 ? ? // CDerive1 和 CBase1 共用的虚函数表
2 ? ? CBase1_CDerive1_VFTable __vftable_base1_derive1;
3 ? ? __vftable_base1_derive1.base1_fun1 = base1_fun1;
4 ? ? __vftable_base1_derive1.derive1_fun1 = derive1_fun1;
?
?
? ? ? ? ?再构造CDerive1覆盖CBase3后的虚函数表:
? ? ? ? ? ? ? 注意: 函数覆盖会替换原来的函数指针
?
1 ? ? CBase3_CDerive1_VFTable __vftable_base3_derive1;
2 ? ? __vftable_base3_derive1.base3_fun1 = base3_derive1_fun1;
?
?
?
?
? ? 6. 开始! 从CDerive1构造一个完整的Derive1类
?
? ? ? ? 先初始化成员变量与__vfptr的指向: 注意不是指错了!
?
复制代码
1 ? ? CDerive1 d1;
? ? ? d1.derive1 = 1;
2?
3 ? ? d1.base1.base1_1 = 11;
4 ? ? d1.base1.__vfptr = reinterpret_cast(&__vftable_base1_derive1);
5 ? ??
6 ? ? d1.base2.base2_1 = 21;
7?
8 ? ? d1.base3.base3_1 = 31;
9 ? ? d1.base3.__vfptr = reinterpret_cast(&__vftable_base3_derive1);
复制代码
? ? ? ?由于目前的CDerive1是我们手动构造的, 不存在真正语法上的继承关系, 如要得到各基类指针, 我们就不能直接来取, 必须手动根据偏移计算:
?
1 ? ? char* p = reinterpret_cast(&d1);
2 ? ? Base1* pb1 = reinterpret_cast(p + 0);
3 ? ? Base2* pb2 = reinterpret_cast(p + sizeof(CBase1) + sizeof(CBase3));
4 ? ? Base3* pb3 = reinterpret_cast(p + sizeof(CBase1));
5 ? ? Derive1* pd1 = reinterpret_cast(p);
?
?
? ? ? 真正调用:
?
1 ? ? foo(pb1, pb2, pb3, pd1);
?
?
?