- 1、本文档共62页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
* (2)多重继承中的二义性问题 在例8-3中,Student类和Teacher类都继承了Person类的成员,TA类继承了Student类和Teacher类的成员,因此,TA中包含了两份Person类的成员(分别从Student类和Teacher类继承)。如果我们通过TA类的对象调用Person类的成员,则在编译程序时会报错。如:coutta.GetName()endl; // 输出姓名 这是由于TA类中有两个分别从Student类和Teacher类继承过来的GetName()函数,直接使用ta对象调用GetName()函数时会有二义性问题,即编译程序不知道应该调用哪个GetName()函数。 8.1 继承 * 为了解决这个问题,我们可以在调用GetName()函数时通过作用域运算符指定要调用从哪个类继承过来的函数。例如: coutta.Student::GetName()endl; 或 coutta.Teacher::GetName()endl; 但这样调用函数需要知道类的继承关系,不方便类的使用。下面介绍另一种使用虚拟继承解决多重继承中二义性问题的方法。 8.1 继承 * (3)虚拟继承和虚基类 在定义派生类时,可以通过虚拟继承方式将基类声明为虚基类。虚基类中的成员在类的继承关系中只会被继承一次,从而解决上述二义性问题。虚拟继承的语法为: class 派生类名 : virtual 继承方式 虚基类名 { …… } 其中,关键字virtual和继承方式的顺序可以调换。 例如,在例8-3中定义Student类和Teacher类时,如果采用虚拟继承方式: class Student : virtual public Person { …… } class Teacher : virtual public Person { …… } 8.1 继承 * 则Person类成为虚基类。此时,TA类从虚基类Person类中继承Person类的成员,从Student类和Teacher类中则只继承了Student类和Teacher类新定义的成员,从而保证TA类中只包含一份Person类的成员、解决了二义性问题。 由于虚基类后继类层次中的类都是直接从虚基类继承其成员,而对这部分成员的初始化需要调用虚基类的构造函数来完成。因此,如果一个派生类同时从基类和虚基类继承了成员,那么在定义该类的构造函数时,除了要调用基类的构造函数、还要调用虚基类的构造函数;析构函数也是如此,当销毁该派生类的对象时,除了会直接调用基类的析构函数、还会直接调用虚基类的析构函数。 8.1 继承 * 【例8-4】采用虚拟继承方式改写例8-3,解决二义性问题。 // VirtualInherit.cpp #include iostream using namespace std; class Person { public: Person(char *name, bool sex) { strcpy(m_name, name); m_sex = sex; coutPerson类构造函数被调用!endl; } ~Person() { coutPerson类析构函数被调用!endl; } void SetName(char *name) { strcpy(m_name, name); } char* GetName() { return m_name; } void SetSex(bool sex) { m_sex = sex; } bool GetSex() { return m_sex; } private: char m_name[20]; // 姓名 bool m_sex; // 性别(true:男,false:女) }; 8.1 继承 * class Student : virtual public Person { public: Student(char *sno, char *name, bool sex, char *major) : Person(name, sex) { strcpy(m_sno, sno); strcpy(m_major, major); coutStudent类构造函数被调用!endl; } ~Student() { coutStudent类析构函数被调用!endl; } void SetSNO(char *sno) { strcpy(m_sno, sno); } char* GetSNO() { return m_sno; } void SetMajor(char *major) { strcpy(m_major, major); } char* GetMa
文档评论(0)