系统基于32位,MSVC编译器,VS开发工具
1、之前看到的都是简单一点的类型继承,现在看下另外一个例子,菱形继承(又称钻石继承)。一个TypeA基类,TypeB和TypeC继承TypeA,TypeD同时继承TypeB和TypeC。
class TypeA {
public:
char a1 = 10;
int a2 = 20;
void virtual TypeA_Method1() {
cout << "TypeA::TypeA_Method1" << endl;
}
void virtual TypeA_Method2() {
cout << "TypeA::TypeA_Method2" << endl;
}
};
class TypeB:public TypeA {
public:
char b1 = 30;
int b2 = 40;
void virtual TypeA_Method1() {//重写了TypeA中的TypeA_Method1
cout << "TypeB::TypeA_Method1" << endl;
}
void virtual TypeB_Method1() {//TypeB类型自己的函数TypeB_Method1
cout << "TypeB::TypeB_Method1" << endl;
}
};
class TypeC:public TypeA {
public:
char c1 = 50;
int c2 = 60;
void virtual TypeA_Method2() {//重写了TypeA中的TypeA_Method2
cout << "TypeC::TypeA_Method2" << endl;
}
void virtual TypeC_Method1() {//TypeC类型自己的函数TypeC_Method1
cout << "TypeC::TypeC_Method1" << endl;
}
void virtual TypeC_Method2() {//TypeC类型自己的函数TypeC_Method2
cout << "TypeC::TypeC_Method2" << endl;
}
};
class TypeD :public TypeB, public TypeC {
public:
char c1 = 70;
int c2 = 80;
void virtual TypeA_Method1() {//重写了TypeA中的TypeA_Method1
cout << "TypeD::TypeA_Method1" << endl;
}
void virtual TypeB_Method1() {//重写了TypeB中的TypeB_Method1
cout << "TypeD::TypeB_Method1" << endl;
}
void virtual TypeC_Method1() {//重写了TypeC中的TypeC_Method1
cout << "TypeD::TypeC_Method1" << endl;
}
void virtual TypeD_Method1() {//TypeD自己的函数TypeD_Method1
cout << "TypeD::TypeD_Method1" << endl;
}
};
int main()
{
TypeD d_obj;
//获取d_obj指针
TypeD* d_ptr = &d_obj;
//d_ptr转换成其内部的TypeB子对象指针
TypeB* b_ptr = d_ptr;
//d_ptr转换成其内部的TypeC子对象指针
TypeC* c_ptr = d_ptr;
//d_ptr内存中有两个TypeA子对象,无法确定转到哪个TypeA
TypeA* a_ptr1 = d_ptr;
//b_ptr转换成其内部的TypeA子对象指针
TypeA* a_ptr2 = b_ptr;
//c_ptr转换成其内部的TypeA子对象指针
TypeA* a_ptr3 = c_ptr;
//先定位到c_ptr地址处,找到TypeC_Method1
d_ptr->TypeC_Method1();
//先定位到a_ptr地址处,找到TypeA_Method2
c_ptr->TypeA_Method2();
//先定位到a_ptr地址处,找到TypeA_Method1
d_ptr->TypeA_Method1();
//先定位到a_ptr地址处,找到TypeA_Method1
c_ptr->TypeA_Method1();
return 1;
}
|
1、d_ptr->TypeC_Method1() 发现TypeC_Method1是TypeC中定义的,所以找到TypeC子对象的地址,通过d_ptr+20,也是__vfptr的地址,再获取对应虚函数指针&TypeD::TypeC_Method1调用。因为是TypeD重写的函数,所以传入d_ptr作为this指针
2、c_ptr->TypeA_Method2() 发现TypeA_Method2是TypeA中定义的,所以找到TypeC部分的TypeA子对象地址,地址和c_ptr值一样,无需变更。通过c_ptr获取__vfptr值,再获取对应虚函数指针&TypeC::TypeA_Method2调用,因为是TypeC重写的函数,所以传入c_ptr作为this指针
3、d_ptr->TypeA_Method1() 发现TypeA_Method1是TypeA中定义,所以找到TypeB部分的TypeA子对象地址。再获取对应虚函数指针&TypeD::TypeA_Method1。因为是TypeD重写的函数,所以传入d_ptr作为this指针
4、c_ptr->TypeA_Method1() 发现是TypeA_Method1是TypeA中定义的,所以找到TypeC部分中的TypeA子对象地址。再获取对应虚函数指针&TypeD::TypeA_Method1。因为是TypeD重写的函数,所以传入c_ptr+20作为this指针
|
|
|