继承

作者: 菜菜子MJ | 来源:发表于2021-05-06 17:40 被阅读0次

转自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()"

相关文章

  • 继承 继承

    属性拷贝 继承不单单能通过原型链实现,也能通过其他方式实现,属性拷贝就是其中一种方法。 通过属性拷贝也能实现继承子...

  • 继承(单继承,多继承)

    将共性的内容放在父类中,子类只需要关注自己特有的内容 python中所有的内容都是对象,所有的对象都直接或间接继承...

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • Python-学习之路-08 OOP -02

    单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类可以继承多个类 单继承的多继承的优缺点 菱形继承/钻石...

  • 原型相关(二)

    1.继承 继承方式:接口继承(只继承方法签名)实现继承(继承实际的方法)ECMAScript只支持实现继承,并且主...

  • 继承

    继承的引入和概述 继承案例和继承的好处 继承的弊端 Java中继承的特点 继承的注意实现和什么时候使用继承 继承中...

  • Java面向对象三大特性之继承

    继承 一、继承的特点 Java只支持单继承单继承 多继承 单继承、多继承优缺点①单继承优点:提高了代码的复用性,让...

  • 7、面向对象的程序设计3(《JS高级》笔记)

    三、继承 许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际方法。由...

  • 【重学前端】JavaScript中的继承

    JavaScript中继承主要分为六种:类式继承(原型链继承)、构造函数继承、组合继承、原型式继承、寄生式继承、寄...

  • js之继承

    文章主讲 JS 继承,包括原型链继承、构造函数继承、组合继承、寄生组合继承、原型式继承、 ES6 继承,以及 多继...

网友评论

      本文标题:继承

      本文链接:https://www.haomeiwen.com/subject/qsvddltx.html