首页 > 代码库 > c++第十章-(多继承与虚继承)

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++进阶版学习。