JHHK

欢迎来到我的个人网站
行者常至 为者常成

11、多继承

目录

多继承

C++允许一个类可以有多个父类(不建议使用,会增加程序设计复杂度)

class Student{
public:
    int score;
    virtual void study(){
        cout<<"Student::study()"<<endl;
    }
    
    Student(){
        cout<<"Student:Student"<<endl;
    }
    
    Student(int score){
        cout<<"Student:Student(int score)"<<endl;
        this->score = score;
    }
};

class Worker{
public:
    int salary;
    virtual void work(){
        cout<<"Worker::work()"<<endl;
    }
    
    Worker(){
        cout<<"Worker::Worker"<<endl;
    }
    
    Worker(int salary){
        cout<<"Worker::Worker(int salary)"<<endl;
        this->salary = salary;
    }
};


class Undergraduate:public Student,public Worker{
public:
    int grade;
    
    void play(){
        cout<<"Undergraduate::play()"<<endl;
    }
    
    Undergraduate(){
        cout<<"Undergraduate:Undergraduate"<<endl;
    }
    
    Undergraduate(int grade){
        cout<<"Undergraduate:Undergraduate(int grade)"<<endl;
        this->grade = grade;
    }
};


void mutiInheritUsing(){
    Undergraduate * grade = new Undergraduate(4);
    grade->score = 100;
    grade->salary = 1000;
    grade->grade = 4;
    grade->study();
    grade->work();
    grade->play();
    delete grade;
}

多继承体系下的构造函数调用

见上边类的继承关系

多继承-虚函数

如果子类继承多个父类都有虚函数,那么子类对象就会产生对应的多张虚表

void multiVirtualUsing(){
    Undergraduate * grade = new Undergraduate();
    grade->score = 100;
    grade->salary = 1000;
    grade->grade = 4;
    cout<<"sizeof(Undergraduate)"<<sizeof(Undergraduate)<<endl;
    
    /**
     (lldb) po grade
     0x0000000100505160

     (lldb) memory read/4xg 0x0000000100505160
     
                    虚表一的地址        变量score的值
     0x100505160: 0x000000010001e328 0x0000000000000064
                    虚表二的地址        变量salary和变量grade的值
     0x100505170: 0x000000010001e340 0x00000004000003e8
     */
}

img

同名函数、同名成员变量

class Animal{
public:
    int age;
    void eat(){
        cout<<"Animal::eat()"<<endl;
    }
    
};

class Quan{
public:
    int age;
    void eat(){
        cout<<"Quan::eat()"<<endl;
    }
};


class Dog:public Animal,public Quan{
public:
    int age;
    void eat(){
        cout<<"Dog::eat()"<<endl;
    }
};

void multiFunAndMemeberVar(){
    
    Dog * dog = new Dog();
    
    //同名函数
    dog->Dog::eat();
    dog->Quan::eat();
    dog->Animal::eat();
    dog->eat();
    
    //同名的成员变量
    dog->age = 10;
    dog->Animal::age = 8;
    dog->Quan::age = 9;
    
    cout<<"dog->Dog::age is "<<dog->Dog::age<<endl;
    cout<<"dog->Animal::age is "<<dog->Animal::age<<endl;
    cout<<"dog->Quan::age is "<<dog->Quan::age<<endl;
    cout<<"dog->age is "<<dog->age<<endl;
    delete dog;
}

菱形继承

class Person{
public:
    int age;
};

class Student:public Person{
public:
    int score;
};

class Worker:public Person{
public:
    int salary;
};

class Undergraduate:public Student,public Worker{
public:
    int grade;
};

img

void lingxingInheritUsing(){
    Undergraduate * grade = new Undergraduate();
    cout<<"sizeof(Undergraduate)"<<sizeof(Undergraduate)<<endl;
    //直接这么写有二义性
//    grade->age = 10;
    
    grade->Student::age = 10;
    grade->Worker::age = 11;
}

虚继承

虚继承可以解决菱形继承带来的问题 Person类被称为虚基类

class Person1{
public:
    int age;
};

class Student1:virtual public Person1{
public:
    int score;
};

class Worker1:virtual public Person1{
public:
    int salary;
};

class Undergraduate1:public Student1,public Worker1{
public:
    int grade;
};


void virtualInheritUsing(){
    Undergraduate1 * grade = new Undergraduate1();
    cout<<"sizeof(Undergraduate1)"<<sizeof(Undergraduate1)<<endl;
    
    //此处不会产生二义性
    grade->age = 10;
}

img

img

多继承的应用

多继承:增加程序的复杂度

多继承有一个很好的用途:
一个类实现多个接口(Java)
一个类遵守多份协议(OC)
一个类继承多个抽象类(C++)

class JobBaomu {
    virtual void clean() = 0;
    virtual void cook() = 0;
};

class JobTeacher {
    virtual void playBaseball() = 0;
    virtual void playFootball() = 0;
};

class SalesMan : public JobBaomu {
public:
    void clean() {

    }

    void cook() {
        
    }
};

class SuperStudent : public JobBaomu, public JobTeacher {
public:
    void clean() {

    }

    void cook() {

    }

    void playBaseball() {

    }

    void playFootball() {

    }
};


void multyInheritApplyUsing(){
    SuperStudent * spuStu = new SuperStudent();
    spuStu->cook();
    delete  spuStu;
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.