C++继承的各种模型

来源:互联网 发布:linux进入命令行界面 编辑:程序博客网 时间:2024/06/10 19:22

首先我们需要知道
如果继承中涉及虚函数 ,就会从在虚表,所谓的虚表就是存储虚函数地址的表格。子类继承的话,子类自己的函数会重写所有父类的满足条件的所有函数,其余的虚函数会保存在第一个父类的虚表中。
如果是虚拟继承的话,在菱形继承的条件下,防止的是数据的冗余,最顶层的父类的内容会保存在模型的最底端,他的一级子类会保存一个虚基表,该表存放的是子类对于他的偏移量。
在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

原创粉丝点击