首先我们需要知道
如果继承中涉及虚函数 ,就会从在虚表,所谓的虚表就是存储虚函数地址的表格。子类继承的话,子类自己的函数会重写所有父类的满足条件的所有函数,其余的虚函数会保存在第一个父类的虚表中。
如果是虚拟继承的话,在菱形继承的条件下,防止的是数据的冗余,最顶层的父类的内容会保存在模型的最底端,他的一级子类会保存一个虚基表,该表存放的是子类对于他的偏移量。
在visual studio2013下,虚表在虚基表的上面。
1.只有成员变量的菱形继承(无虚拟继承)和只有成员变量的菱形虚拟继承(钻石继承)
2.只有虚函数的菱形继承(无虚拟继承)
3.只有虚函数的菱形虚拟继承(钻石继承)
4.既有成员变量,又有虚函数的菱形继承(无虚拟继承)
5.既有成员变量,又有虚函数的菱形虚拟继承
#include<iostream>
using namespace std;
typedef void(*p) (void);
void print(int** ptr)
{
int index = 0;
printf("0x%p\n", ptr);
for (; ptr[index] != NULL; index++)
{
printf("virtual table [%d]:%p-->", index, ptr[index]);
p fun = (p)(ptr[index]);
fun();
}
cout << endl;
}
void printvirtualbasetable(int* ptr)
{
cout << ptr << endl;
//cout << *(ptr) << endl;
cout << *(ptr+1) << endl;
}
class A
{
public:
virtual void a1()
{
cout << "A::a1()" << endl;
}
virtual void a2()
{
cout << "A::a2()" << endl;
}
};
class B :virtual public A
{
public:
virtual void b1()
{
cout << "B::b1()" << endl;
}
};
class C :virtual public A
{
public:
virtual void c1()
{
cout << "C::c1()" << endl;
}
};
class D :public B, public C
{
public:
virtual void a1()
{
cout << "D::a1()" << endl;
}
virtual void d1()
{
cout << "D::d1()" << endl;
}
};
//class A
//{
//public:
// int a;
//};
//
//class B:virtual public A
//{
//public:
// int b;
//};
//
//class C:virtual public A
//{
//public:
// int c;
//};
//
//class D:public B,public C
//{
//public:
// int d;
//};
int main()
{
D d;
//d.b = 2;
//d.c = 3;
//d.d = 4;
//d.B::a = 5;
//d.C::a = 6;
printvirtualbasetable((int*)*((int*)(&d)+1));
//printvirtualbasetable((int*)*((int*)(&d)+2));
d.B::a = 5;
//d.C::a = 6;
print((int**)*(int**)(&d));
//print((int**)*(((int**)(&d)) + 1));
//print((int**)*(((int**)(&d)) + 4));
//printvirtualbasetable((int*)*((int*)(&d)));
//printvirtualbasetable((int*)*((int*)(&d) + 1));
//printvirtualbasetable((int*)*((int*)(&d) + 3));
cout << sizeof(d) << endl;
//print((int**)*(int**)(&d));
//print((int**)*(int**)(((char*)(&d))+12));
/*int* ptrb = (int*)*((int*)(&d)+1);
int* ptrc = (int*)*((int*)(&d)+4);
printvirtualbasetable(ptrb);
printvirtualbasetable(ptrc);
int** vptrb = (int**)*(int**)(&d);
print(vptrb);
int** vptrc = (int**)*(int**)(((char*)(&d))+12);
print(vptrc);
int** vptra = (int**)*(int**)(((char*)(&d)) +28);
print(vptra);
cout << *(int*)(((char*)(&d)) + 8) << endl;
cout << *(int*)(((char*)(&d)) + 24) << endl;
cout << *(int*)(((char*)(&d)) + 32) << endl;*/
return 0;
}
//int main()
//{
// C c;
// A* ptra = &c;
// B* ptrb = &c;
// int** ptr1 = (int**)(*(int**)(ptra));
// print(ptr1);
// int** ptr2 = (int**)(*(int**)(ptrb));
// c.a = 10;
// c.b = 20;
// c.c = 30;
//
//
// int x = (int)*((int**)(&c) + 1);
// cout << x << endl;
//
// printf("%p\n", (int**)(((int**)(&c)) + 1));
// print(ptr2);
//
// B b;
// int** ptr1 = (int**)(*(int**)(&b));
// int** ptr2 = (int**)(*((int**)(&d) + 2));
// int** ptr3 = (int**)(*((int**)(&d) + 4));
// int** ptr4 = (int**)(*((int**)(&d) + 3));
// print(ptr1);
// print(ptr2);
// print(ptr3);
// print(ptr4);
// d.a = 10;
// return 0;
//}
//class A{
//public:
// int a;
//};
//
//class B :virtual public A
//{
//public:
// int b;
//};
//
//class C :virtual public A
//{
//public:
// int c;
//};
//
//class D :public B, public C
//{
//public:
// int d;
//};
//
//int main()
//{
// D d;
// d.a=1;
// d.b=2;
// d.c=3;
// d.d=4;
// printvirtualbasetable((int*)*(int*)(&d));
// return 0;
//}
github代码下载地址:
https://github.com/q45101218/CppTest/blob/master/Inherit/allinheritance.cpp