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