继承

2021-05-06  本文已影响0人  菜菜子MJ

转自https://blog.csdn.net/qq_36359022/article/details/81870219

多重单继承 Class A -> Class B -> Class C

多重单继承虚函数表.png
class ClassA
{
public:
    ClassA() { cout << "ClassA::ClassA()" << endl; }
    virtual ~ClassA() { cout << "ClassA::~ClassA()" << endl; }

    void func1() { cout << "ClassA::func1()" << endl; }
    void func2() { cout << "ClassA::func2()" << endl; }

    virtual void vfunc1() { cout << "ClassA::vfunc1()" << endl; }
    virtual void vfunc2() { cout << "ClassA::vfunc2()" << endl; }
private:
    int aData;
};

class ClassB : public ClassA
{
public:
    ClassB() { cout << "ClassB::ClassB()" << endl; }
    virtual ~ClassB() { cout << "ClassB::~ClassB()" << endl; }

    void func1() { cout << "ClassB::func1()" << endl; }
    virtual void vfunc1() { cout << "ClassB::vfunc1()" << endl; }
private:
    int bData;
};

class ClassC : public ClassB
{
public:
    ClassC() { cout << "ClassC::ClassC()" << endl; }
    virtual ~ClassC() { cout << "ClassC::~ClassC()" << endl; }

    void func2() { cout << "ClassC::func2()" << endl; }
    virtual void vfunc2() { cout << "ClassC::vfunc2()" << endl; }
private:
    int cData;
};

ClassA类型的指针a能操作的范围只能是黑框中的范围,之所以实现了多态完全是因为子类的虚函数表指针与虚函数表的内容与基类不同

ClassA* a = new ClassC;
a->func1();          // "ClassA::func1()"   隐藏ClassB::func1()               
a->func2();          // "ClassA::func2()"   隐藏ClassC::func2()
a->vfunc1();         // "ClassB::vfunc1()"  ClassB把ClassA::vfunc1()覆盖了
a->vfunc2();         // "ClassC::vfunc2()"  ClassC把ClassA::vfunc2()覆盖了

ClassB* b = new ClassC;
b->func1();             // "ClassB::func1()"    有权限操作时,子类优先
b->func2();             // "ClassA::func2()"    隐藏ClassC::func2()
b->vfunc1();            // "ClassB::vfunc1()"   ClassB把ClassA::vfunc1()覆盖了
b->vfunc2();            // "ClassC::vfunc2()"   ClassC把ClassA::vfunc2()覆盖了

同时继承多个基类ClassA1->ClassC & ClassA2->ClassC

同时继承多个基类虚函数表.png

虚函数表指针02位置错了,其应该再往下偏移sizeof(A)

class ClassA1
{
public:
    ClassA1() { cout << "ClassA1::ClassA1()" << endl; }
    virtual ~ClassA1() { cout << "ClassA1::~ClassA1()" << endl; }

    void func1() { cout << "ClassA1::func1()" << endl; }

    virtual void vfunc1() { cout << "ClassA1::vfunc1()" << endl; }
    virtual void vfunc2() { cout << "ClassA1::vfunc2()" << endl; }
private:
    int a1Data;
};

class ClassA2
{
public:
    ClassA2() { cout << "ClassA2::ClassA2()" << endl; }
    virtual ~ClassA2() { cout << "ClassA2::~ClassA2()" << endl; }

    void func1() { cout << "ClassA2::func1()" << endl; }

    virtual void vfunc1() { cout << "ClassA2::vfunc1()" << endl; }
    virtual void vfunc2() { cout << "ClassA2::vfunc2()" << endl; }
    virtual void vfunc4() { cout << "ClassA2::vfunc4()" << endl; }
private:
    int a2Data;
};

class ClassC : public ClassA1, public ClassA2
{
public:
    ClassC() { cout << "ClassC::ClassC()" << endl; }
    virtual ~ClassC() { cout << "ClassC::~ClassC()" << endl; }

    void func1() { cout << "ClassC::func1()" << endl; }

    virtual void vfunc1() { cout << "ClassC::vfunc1()" << endl; }
    virtual void vfunc2() { cout << "ClassC::vfunc2()" << endl; }
    virtual void vfunc3() { cout << "ClassC::vfunc3()" << endl; }
};

当有多个虚函数表时,虚函数表的结果是0代表没有下一个虚函数表。" * "号位置在不同操作系统中实现不同,代表有下一个虚函数表。
1.子类虚函数会覆盖每一个父类的每一个同名虚函数。
2.父类中没有的虚函数而子类有,填入第一个虚函数表中,且用父类指针时不能调用。
3.父类中有的虚函数而子类没有,则不覆盖。仅子类和该父类指针能调用。

    ClassA1 *a1 = new ClassC;
    a1->func1();               // "ClassA1::func1()"    隐藏子类同名函数
    a1->vfunc1();              // "ClassC::vfunc1()"    覆盖父类ClassA1虚函数
    a1->vfunc2();              // "ClassC::vfunc2()"    覆盖父类ClassA1虚函数
    没有a1->vfunc3(),父类没有这个虚函数

    ClassA2 *a2 = new ClassC;
    a2->func1();               // "ClassA2::func1()"    隐藏子类同名函数
    a2->vfunc1();              // "ClassC::vfunc1()"    覆盖父类ClassA2虚函数
    a2->vfunc2();              // "ClassC::vfunc2()"    覆盖父类ClassA2虚函数
    a2->vfunc4();              // "ClassA2::vfunc4()"   未被子类重写的父类虚函数

    ClassC *c = new ClassC;
    c->func1();                // "ClassC::func1()"
    c->vfunc1();               // "ClassC::vfunc1()"
    c->vfunc2();               // "ClassC::vfunc2()"
    c->vfunc3();               // "ClassC::vfunc3()"
    c->vfunc4();               // "ClassA2::func4()"

上一篇 下一篇

猜你喜欢

热点阅读