c++第十章-(多继承与虚继承)

多继承

class Person
{
public:
    Person(std::string theName);
    
    void introduce();
    
protected:
    std::string name;
};


class Teacher : public Person
{
public:
    Teacher(std::string theName,std::string theClass);
    
    void teach();
    void introduce();
    
protected:
    std::string classes;
};

class Student : public Person
{
public:
    Student(std::string theName,std::string theClass);
    
    void attendClass();
    void introduce();
protected:
    std::string classes;
};

Person::Person(std::string theName)
{
    this->name = theName;
}

void Person::introduce()
{
    std::cout << "大家好,我是" << name << ".\n\n";
}

Teacher::Teacher(std::string theName,std::string theClass) : Person(theName)
{
    this->classes = theClass;
}

void Teacher::teach()
{
    std::cout << this->name << "" << classes << ".\n\n";
}

void Teacher::introduce()
{
    std::cout << "大家好,我是" << name << ",我教" << classes << ".\n\n";
}

Student::Student(std::string theName,std::string theClass) : Person(theName)
{
    this->classes = theClass;
}

void Student::attendClass()
{
    std::cout << name << "加入" << classes << "学习。\n\n";
}

void Student::introduce()
{
    std::cout << "大家好,我是" << name << ",我在" << classes << "学习.\n\n";
}

class TeachingStudent : public Student,public Teacher
{
public:
    TeachingStudent(std::string theName,std::string classTeaching,std::string classAttending);
    
    void introduce();
};

TeachingStudent::TeachingStudent(std::string theName,std::string classTeaching,std::string classAttending) : Teacher(theName,classTeaching),Student(theName,classAttending)
{
    
}

void TeachingStudent::introduce()
{
    std::cout << "大家好,我是" << Student::name << ".我教" << Teacher::classes << ",";
    std::cout << "同时我在" << Student::classes << "学习.\n\n";
}

int main(int argc, const char * argv[])
{
    Teacher teacher("小甲鱼","C++入门班");
    Student student("迷途羔羊","C++入门班");
    TeachingStudent teachingStudent("丁丁","C++入门班","C++进阶版");
    
    teacher.introduce();
    teacher.teach();
    
    student.introduce();
    student.attendClass();
    
    teachingStudent.introduce();
    teachingStudent.teach();
    teachingStudent.attendClass();
    
    return 0;
}

控制台返回结果是:

大家好,我是小甲鱼,我教C++入门班.

小甲鱼教C++入门班.

大家好,我是迷途羔羊,我在C++入门班学习.

迷途羔羊加入C++入门班学习。

大家好,我是丁丁.我教C++入门班,同时我在C++进阶版学习.

丁丁教C++入门班.

丁丁加入C++进阶版学习。

 虚继承

TeachingStudent对象里继承了2个不同的classes属性,也就说也继承了2个不同的name属性。

但当我们的预期是同一个人的时候去做2件不同事的时候,就存在分裂多1个不必要的人了!就TeachingStudent类继承于Teacher和Student两个类,因而继承了两组Person类的属性。这个时候Person类的name属性就会引起麻烦。

class Person
{
public:
    Person(std::string theName);
    
    void introduce();
    
protected:
    std::string name;
};


class Teacher :  public Person
{
public:
    Teacher(std::string theName,std::string theClass);
    
    void teach();
    void introduce();
    
protected:
    std::string classes;
};

class Student : public Person
{
public:
    Student(std::string theName,std::string theClass);
    
    void attendClass();
    void introduce();
protected:
    std::string classes;
};

Person::Person(std::string theName)
{
    this->name = theName;
}

void Person::introduce()
{
    std::cout << "大家好,我是" << name << ".\n\n";
}

Teacher::Teacher(std::string theName,std::string theClass) : Person(theName)
{
    this->classes = theClass;
}

void Teacher::teach()
{
    std::cout << this->name << "" << classes << ".\n\n";
}

void Teacher::introduce()
{
    std::cout << "大家好,我是" << name << ",我教" << classes << ".\n\n";
}

Student::Student(std::string theName,std::string theClass) : Person(theName)
{
    this->classes = theClass;
}

void Student::attendClass()
{
    std::cout << name << "加入" << classes << "学习。\n\n";
}

void Student::introduce()
{
    std::cout << "大家好,我是" << name << ",我在" << classes << "学习.\n\n";
}

class TeachingStudent : public Student,public Teacher
{
public:
    TeachingStudent(std::string theName1,std::string theName2,std::string classTeaching,std::string classAttending);//
    
    void introduce();
};

TeachingStudent::TeachingStudent(std::string theName1,std::string theName2,std::string classTeaching,std::string classAttending) : Teacher(theName1,classTeaching),Student(theName2,classAttending)//
{
    
}

void TeachingStudent::introduce()
{
    std::cout << "大家好,我是" << Student::name << ".我教" << Teacher::classes << ",";
    std::cout << "同时我在" << Student::classes << "学习.\n\n";
}

int main(int argc, const char * argv[])
{
    Teacher teacher("小甲鱼","C++入门班");
    Student student("迷途羔羊","C++入门班");
    TeachingStudent teachingStudent("丁丁","丹丹","C++入门班","C++进阶版");//
    
    teacher.introduce();
    teacher.teach();
    
    student.introduce();
    student.attendClass();
    
    teachingStudent.introduce();
    teachingStudent.teach();
    teachingStudent.attendClass();
    
    return 0;
}

控制台打印结果:

大家好,我是小甲鱼,我教C++入门班.

小甲鱼教C++入门班.

大家好,我是迷途羔羊,我在C++入门班学习.

迷途羔羊加入C++入门班学习。

大家好,我是丹丹.我教C++入门班,同时我在C++进阶版学习.

丁丁教C++入门班.

丹丹加入C++进阶版学习。

这个时候,c++发明者为了解决这个问题,提供了“虚继承”(virtual inheritance)。

虚继承的语法:class Teacher : virtual public Person{...},这样做就解决了问题:让Student和Teacher类都虚继承自Person类,编译器将确保从Studnet何Teacher类再派生出来的子类只能拥有一份Person类的属性。

class Person
{
public:
    Person(std::string theName);
    
    void introduce();
    
protected:
    std::string name;
};


class Teacher : virtual public Person//虚继承,保证了只保留1份Person类的属性,实际上表明没有继承Person的属性
{
public:
    Teacher(std::string theName,std::string theClass);
    
    void teach();
    void introduce();
    
protected:
    std::string classes;
};

class Student : virtual public Person//虚继承,保证了只保留1份Person类的属性,实际上表明没有继承Person的属性
{
public:
    Student(std::string theName,std::string theClass);
    
    void attendClass();
    void introduce();
protected:
    std::string classes;
};

Person::Person(std::string theName)
{
    this->name = theName;
}

void Person::introduce()
{
    std::cout << "大家好,我是" << name << ".\n\n";
}

Teacher::Teacher(std::string theName,std::string theClass) : Person(theName)
{
    this->classes = theClass;
}

void Teacher::teach()
{
    std::cout << this->name << "" << classes << ".\n\n";
}

void Teacher::introduce()
{
    std::cout << "大家好,我是" << name << ",我教" << classes << ".\n\n";
}

Student::Student(std::string theName,std::string theClass) : Person(theName)
{
    this->classes = theClass;
}

void Student::attendClass()
{
    std::cout << name << "加入" << classes << "学习。\n\n";
}

void Student::introduce()
{
    std::cout << "大家好,我是" << name << ",我在" << classes << "学习.\n\n";
}

class TeachingStudent : public Student,public Teacher
{
public:
    TeachingStudent(std::string theName,std::string classTeaching,std::string classAttending);
    
    void introduce();
};

TeachingStudent::TeachingStudent(std::string theName,
                                 std::string classTeaching,
                                 std::string classAttending)
:
Teacher(theName,classTeaching),
Student(theName,classAttending),
Person(theName)//因为之前的Tearcher和Student都是虚继承,所以这里要再次继承于Person类的构造方法
{
    
}

void TeachingStudent::introduce()
{
    std::cout << "大家好,我是" << name << ".我教" << Teacher::classes << ",";//因为是虚继承,子类只保留1份属性,所以这里可以直接写name
    std::cout << "同时我在" << Student::classes << "学习.\n\n";
}

int main(int argc, const char * argv[])
{
    Teacher teacher("小甲鱼","C++入门班");
    Student student("迷途羔羊","C++入门班");
    TeachingStudent teachingStudent("丁丁","C++入门班","C++进阶版");
    
    teacher.introduce();
    teacher.teach();
    
    student.introduce();
    student.attendClass();
    
    teachingStudent.introduce();
    teachingStudent.teach();
    teachingStudent.attendClass();
    
    return 0;
}

控制台打印结果:

大家好,我是小甲鱼,我教C++入门班.

小甲鱼教C++入门班.

大家好,我是迷途羔羊,我在C++入门班学习.

迷途羔羊加入C++入门班学习。

大家好,我是丁丁.我教C++入门班,同时我在C++进阶版学习.

丁丁教C++入门班.

丁丁加入C++进阶版学习。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值