继承,菱形继承,多态,虚继承、菱形虚拟继承

面的代码主要写了关于:
(1).继承和派生的关系
(2).6个默认函数的继承(拷贝,拷贝构造,赋值,析构,...)
(3).普通菱形继承
(4).多重虚继承
(5).多态
(6).虚表
(7).虚菱形继承
     其中涉及到了很多C++中的内容,如<重载,隐藏,覆盖>,<虚基类,虚函数>,<单继承,多继承(菱形继承)> 等等
#ifndef INHERIT_H_  
#define INHERIT_H_  
#include <iostream>  
#include <string>  
using namespace std;  
  
//继承和派生  
  
//继承与派生类的关系  
namespace Relation  
{  
    class Person  
    { //基类  
    public:  
        void fun()  
        {}  
        void show()  
        {  
            cout << _name << endl;  
        }  
        ~Person()  
        {  
            cout << "~Person" << endl;  
        }  
    public:  
        string _name;  
    };  
  
    class Student :protected Person  
    { // 派生类  
    public:  
        void show()  
        {  
            cout << _name << " " << _id << endl;  
        }  
        ~Student()  
        {  
            cout << "~Student" << endl;  
            //~Person(); //不能手动调用  
            Person::~Person(); //这样才可以调用  
        }  
  
    public:  
        /* 将数据成员设置成public确实不符合封装的理念, 
        但是我们是在找规律,所以这样做可以在类外改变数据成员,易于观察变化*/  
        int _id;   
    };  
  
    void test()  
    {  
        Person p;  
        Student s;  
        Person* p1 = &p;  
        //Person* p2 = &s; //共有继承时可以,保护和私有继承时却不可以  
        //s->fun(); //保护或者私有继承的时候,s不能访问的东西,p2是可以访问的,不合逻辑  
        //p2->fun(); //effective c++ 中讲到的has_a关系  
  
        Person& p3 = p;  
        //Person& p4 = s; //共有继承时可以,保护和私有继承时却不可以  
  
        Student* s1 = (Student*)&p;  
        //s1->_id = 0; //该段不属于s1,不能访问(写),相当于是借来的  
        Student* s2 = &s;  
        Student& s3 = (Student&)p;  
        //s3._id = 0; //该段不属于s3,不能访问(写),相当于是借来的  
        Student& s4 = s;  
    }  
}  
  
  
//6个默认函数的继承  
namespace FUNC  
{  
    class Person  
    {  
    public:  
        Person(const char* str = "")  
            :_name(str)  
        {//构造函数  
            cout << "Person(const char* str = "")" << endl;  
        }  
        Person(const Person& p)  
            :_name(p._name)  
        {//拷贝构造函数  
            cout << "Person(const Person& p)" << endl;  
        }  
        Person& operator=(const Person& p)  
        {//赋值语句  
            if (this != &p)  
            {  
                _name = p._name;  
                cout << "Person& operator=(const Person& p)" << endl;  
            }  
            return *this;  
        }  
        ~Person()  
        {//析构函数  
            cout << "~Person" << endl;  
        }  
    public:  
        string _name;  
    };  
  
    class Student :public Person  
    {  
    public:  
        Student(const char* s = "", int id = 0)  
            :Person(s)  
            , _id(id)  
        {  
                cout << "Student(const char* s ,int id) " << endl;  
        }  
  
        Student(const Student& s)  
            :Person(s) //发生切片  
        {  
                _id = s._id;  
                cout << "Student(const Student& s)" << endl;  
        }  
  
        Student& operator=(const Student& s)  
        {  
            if (this != &s)  
            {  
                Person::operator=(s); //也会发生切片  
                _id = s._id;  
                cout << "Student& operator=(const Student& s)" << endl;  
            }  
            return *this;  
        }  
  
        ~Student()  
        {  
            cout << "~Student" << endl;  
            //~Person(); //不能手动调用  
            //Person::~Person(); //这样才可以调用  
        }  
    public:  
        void show()  
        {  
            cout << _name << " " << _id << endl;  
        }  
  
        int _id;  
    };  
  
    void test()  
    {  
        Person p("hello");  
        Student s1("hello world", 2);  
        Student s2(s1);  
        Student s3;  
        s3 = s2;  
    }  
}  
  
//多继承(菱形继承)  
namespace MULTIPLE_INHERITANCE  
{  
    class A  
    {  
    public:  
        void func_a()  
        {  
            cout << "A-func" << endl;  
        }  
  
        int a;  
    };  
  
    class B : virtual public A //继承A  
    {  
    public:  
        void func_b()  
        {  
            cout << "B-func" << endl;  
        }  
        int b;  
    };  
      
    class C :virtual public A //继承A  
    {  
    public:  
        void func_c()  
        {  
            cout << "C-func" << endl;  
        }  
        int c;  
    };  
      
    class D :public B, public C //继承B,C  
    {  
    public:  
        void func_d()  
        {  
            cout << "D-func" << endl;  
        }  
        int d;  
    };  
  
    void test()  
    {  
        A a;  
        B b;  
        C c;  
        D d;  
        /***************************************************************************************************/  
        //通过内存变化可分析,虚继承与普通继承的区别  
  
        //非虚基类  
        /*d.B::a = 1; 
        d.b = 2; 
        d.C::a = 3; 
        d.c = 4; 
        d.d = 5; 
        cout << sizeof(a) << endl; //4 
        cout << sizeof(b) << endl; //8 
        cout << sizeof(c) << endl; //8 
        cout << sizeof(d) << endl; //20 可以看出a被继承了两次 
        */  
        //虚基类  
        d.B::a = 1;  
        d.b = 2;  
        d.C::a = 3;  
        d.c = 4;  
        d.d = 5;  
        cout << sizeof(a) << endl; //4  
        cout << sizeof(b) << endl; //12 a,b,加上一个指向虚基类的指针(严格来说不是指针,只是偏移量)  
        cout << sizeof(c) << endl; //12 a,c,加上一个指向虚基类的指针(严格来说不是指针,只是偏移量)  
        cout << sizeof(d) << endl; //24 a b c d  
        /***************************************************************************************************/  
    }  
}  
  
//多重虚继承  
namespace MULTIPLE_MANY  
{  
    class A  
    {  
    public:  
        virtual void funA()  
        {  
            cout << "A-fun" << endl;  
        }  
        virtual void fun_A()  
        {  
            cout << "A-fun_A" << endl;  
        }  
  
        int a;  
    };  
  
    class B  
    {  
    public:  
        virtual void funB()  
        {  
            cout << "B-fun" << endl;  
        }  
        virtual void fun_B()  
        {  
            cout << "B-fun_B" << endl;  
        }  
  
        int b;  
    };  
  
    class C  
    {  
    public:  
        virtual void funC()  
        {  
            cout << "C-fun" << endl;  
        }  
        virtual void fun_C()  
        {  
            cout << "C-fun_C" << endl;  
        }  
  
        int c;  
    };  
  
    class D :public A, public B, public C  
    {  
    public:  
        virtual void funA()  
        {  
            cout << "D-funA" << endl;  
        }  
        virtual void funB()  
        {  
            cout << "D-funB" << endl;  
        }  
        virtual void funC()  
        {  
            cout << "D-funC" << endl;  
        }  
        virtual void funD()  
        {  
            cout << "fun-D" << endl;  
        }  
  
        int d;  
    };  
  
    typedef void(*Fun)();  
  
    void PrintVtable(int* PTable)  
    {  
        printf("虚表地址:%p\n", PTable);  
        for (int i = 0; PTable[i] != 0; ++i)  
        {  
            printf("第%d个虚函数:%p ", i, PTable[i]);  
            Fun p = (Fun)PTable[i];  
            p();  
        }  
        printf("\n");  
    }  
  
    void test()  
    {  
        D d;  
        d.a = 1;  
        d.b = 2;  
        d.c = 3;  
        d.d = 4;  
        //虚表A  
        int* Vtable1 = (int*)*(int*)(&d); //根据在内存中分布位置来转化  
        PrintVtable(Vtable1);  
        //虚表B  
        int* Vtable2 = (int*)*((int*)(&d) + sizeof(A) / 4); //根据在内存中分布位置来转化  
        PrintVtable(Vtable2);  
        //虚表C  
        int* Vtable3 = (int*)*((int*)(&d) + (sizeof(A)+sizeof(B)) / 4); //根据在内存中分布位置来转化  
        PrintVtable(Vtable3);  
    }  
}  
  
//多态  
namespace POLYMORPHISM  
{  
    class A  
    {  
    public:  
        void fun1() //隐藏  
        {  
            cout << "A-func-1" << endl;  
        }  
        virtual void fun2() //覆盖的条件需要注意  
        {  
            cout << "A-func-2" << endl;  
        }  
        virtual A* fun3()  
        {  
            cout << "A-func-3(协变)" << endl;  
            return this;  
        }  
        //*重载的条件:作用域必须相同*  
        //下面两个函数才构成重载  
        void fun4()  
        {  
            cout << "void fun4()" << endl;  
        }  
        void fun4(int a)  
        {  
            cout << "void fun4(int)重载" << endl;  
        }  
    private:  
        int a;  
    };  
  
    class B : public A //继承A  
    {  
    public:  
        int fun1()  
        {  
            cout << "B-func-1隐藏" << endl;  
            return 0;  
        }  
        virtual void fun2() //覆盖的条件需要注意  
        {  
            cout << "B-func-2覆盖" << endl;  
        }  
        virtual B* fun3()  
        {  
            cout << "B-func-3覆盖(协变)" << endl;  
            return this;  
        }  
    private:  
        int b;  
    };  
  
    void test()  
    {  
        A a;  
        B b;  
        A* p1;  
        p1 = &a;  
        cout << "隐藏" << endl;  
        a.fun1();  
        b.fun1();  
        cout << "重载" << endl;  
        p1->fun4();  
        p1->fun4(0);  
        cout << "隐藏和覆盖" << endl;  
        p1->fun1();  
        p1->fun2();  
        p1->fun3();  
        p1 = &b;  
        p1->fun1();  
        p1->fun2();  
        p1->fun3();  
    }  
}  
  
//虚表  
namespace VIRTUAL_FUNC  
{  
    class Base1 {  
    public:  
        virtual void f() { cout << "Base1::f" << endl; }  
        virtual void g() { cout << "Base1::g" << endl; }  
        virtual void h() { cout << "Base1::h" << endl; }  
  
    };  
  
    class Base2 {  
    public:  
        virtual void f() { cout << "Base2::f" << endl; }  
        virtual void g() { cout << "Base2::g" << endl; }  
        virtual void h() { cout << "Base2::h" << endl; }  
    };  
  
    class Base3 {  
    public:  
        virtual void f() { cout << "Base3::f" << endl; }  
        virtual void g() { cout << "Base3::g" << endl; }  
        virtual void h() { cout << "Base3::h" << endl; }  
    };  
  
    class Derive : public Base1, public Base2, public Base3 {  
    public:  
        virtual void f() { cout << "Derive::f" << endl; }  
        virtual void g1() { cout << "Derive::g1" << endl; }  
    };  
  
    typedef void(*Fun)(void);  
  
    void test()  
    {  
        Fun pFun = NULL;  
  
        Derive d;  
        int** pVtab = (int**)&d;  
  
        //Base1's vtable  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+0);  
        pFun = (Fun)pVtab[0][0];  
        pFun();  
  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+1);  
        pFun = (Fun)pVtab[0][1];  
        pFun();  
  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+2);  
        pFun = (Fun)pVtab[0][2];  
        pFun();  
  
        //Derive's vtable  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+3);  
        pFun = (Fun)pVtab[0][3];  
        pFun();  
  
        //The tail of the vtable  
        pFun = (Fun)pVtab[0][4];  
        cout << pFun << endl;  
  
        //Base2's vtable  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+0);  
        pFun = (Fun)pVtab[1][0];  
        pFun();  
  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+1);  
        pFun = (Fun)pVtab[1][1];  
        pFun();  
  
        pFun = (Fun)pVtab[1][2];  
        pFun();  
  
        //The tail of the vtable  
        pFun = (Fun)pVtab[1][3];  
        cout << pFun << endl;  
  
        //Base3's vtable  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+0);  
        pFun = (Fun)pVtab[2][0];  
        pFun();  
  
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+1);  
        pFun = (Fun)pVtab[2][1];  
        pFun();  
  
        pFun = (Fun)pVtab[2][2];  
        pFun();  
  
        //The tail of the vtable  
        pFun = (Fun)pVtab[2][3];  
        cout << pFun << endl;  
    }  
  
}  
  
//虚钻石继承  
namespace VIRTUAL_RING  
{  
    typedef void(*Func)();  //函数指针  
  
    void PrintVTable(int *VTable)  
    {  
        cout << "虚表地址:" << VTable << endl;  
        for (int i = 0; VTable[i] != 0; i++)  
        {  
            printf("第VTable[%d]是:OX%p->", i, VTable[i]);  
            Func p = (Func)VTable[i];  
            p();  
        }  
        cout << endl;  
    }  
  
    class A  
    {  
    public:  
        virtual void fun1()  
        {  
            cout << "A-func1" << endl;  
        }  
        virtual void fun2()  
        {  
            cout << "A-func2" << endl;  
        }  
  
        int a;  
    };  
  
    class B : virtual public A //继承A  
    {  
    public:  
        virtual void fun1()  
        {  
            cout << "B-func1" << endl;  
        }  
        virtual void fun3()  
        {  
            cout << "B-func3" << endl;  
        }  
  
        int b;  
    };  
  
    class C :virtual public A //继承A  
    {  
    public:  
        virtual void fun1()  
        {  
            cout << "C-func1" << endl;  
        }  
        virtual void fun4()  
        {  
            cout << "C-func4" << endl;  
        }  
  
        int c;  
    };  
  
    class D :public B, public C //继承B,C  
    {  
    public:  
        virtual void fun1()  
        {  
            cout << "D-func1" << endl;  
        }  
        virtual void fun5()  
        {  
            cout << "D-func5" << endl;  
        }  
        int d;  
    };  
  
    void test()  
    {  
        cout << "虚表A:" << endl;  
        A a;  
        int *fa1 = (int *)(*(int *)&a);  
        PrintVTable(fa1);  
  
        cout << "虚表B:" << endl;  
        B b;  
        int* fa2 = (int *)(*(int *)&b);  
        PrintVTable(fa2);  
        fa2 = (int *)*(int *)((char *)&b + sizeof(B)-sizeof(A));  
        PrintVTable(fa2);  
  
        cout << "虚表C:" << endl;  
        C c;  
        int* fa3 = (int *)(*(int *)&c);  
        PrintVTable(fa3);  
        fa3 = (int *)*(int *)((char *)&c + sizeof(C)-sizeof(A));  
        PrintVTable(fa3);  
  
        cout << "虚表D" << endl;  
        D d;  
        d.a = 1;  
        d.b = 2;  
        d.c = 3;  
        d.d = 4;    //记得打开调试找到&d,然后好好看看地址分配,便于下面的操作  
        //虚表1  
        int* fa4 = (int *)(*(int *)&d);  
        PrintVTable(fa4);  
        //虚表2  
        fa4 = (int*)*((int*)&d + sizeof(B) / 4 - 2); //根据在内存中的分布来转化  
        PrintVTable(fa4);  
        //虚表3  
        fa4 = (int*)*((int*)&b + (sizeof(B)+sizeof(C)) / 4 - 3); //根据在内存中的分布来转化  
        PrintVTable(fa4);  
  
        A* p;  
        p = &a;  
        p->fun1();  
        p->fun2();  
        p = &b;  
        p->fun1();  
        p->fun2();  
        p = &c;  
        p->fun1();  
        p->fun2();  
        p = &d;  
        p->fun1();  
        p->fun2();  
  
    }  
}  
  
#endif  


我这篇博客没有细说,知识将我研究它们关系以及特点的时候的代码给出来了,其实我也准备好好写出来的,我也整理了其中很多的内容,我将它们截图下来了,其中的一些图如下:


1.关于虚表:

1.虚表


2.普通菱形继承


3.菱形继承,虚继承


4.虚拟菱形继承




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值