1.实验目的
(1)理解继承的含义,掌握派生类的定义方法和实现。
(2)理解公有继承下基类成员对派生类成员和派生类对象的可见性,能正确地访问继承层次中的各种类成员。
(3)掌握多重继承的概念、定义方法,熟悉多重继承派生类构造函数的执行顺序。
说明:多重继承派生类构造函数的执行顺序:①先执行所有基类的构造函数(顺序按照定义派生类时指定的各基关顺序),②再执行对象成员所在类的构造函数(顺序按照它们在类中的声明顺序) ,③最后执行派生类构造函数体中的内容。
2.实验内容
(1)继承访问权限
#include
using namespace std;
class Base
{
public:
void setx(int i){ x=i;}
int getx(){return x;}
public:
int x;
};
class Derived: public Base
{
public:
void sety(int i){ y=i; }
int gety(){return y;}
void show(){ cout<<”Base::x=”< public: int y; }; int main() { Derived bb; bb.setx(16); bb.sety(25); bb.show(); cout<<”Base::x=”< cout<<”Derived::y=”< cout<<”Base::x=”< cout<<”Derived::y=”< return 0; } 写出程序的运行结果。 按以下要求,对程序进行修改后再调试,指出调试中出错的原因。 ①将基类Base中数据成员x的访问权限改为private时,会出现哪些错误?为什么? ②将基类Base中数据成员x的访问权限改为protected时,会出现哪些错误?为什么? ③在源程序的基础上,将派生类Derived的继承方式改为private时,会出现哪些错误?为什么? ④在源程序的基础上,将派生类Derived的继承方式改为protected时,会出现哪些错误?为什么? (2) 派生类对象构造过程 先阅读下面的程序,写出程序执行结果,然后再上机运行,验证自己分析的结果是否正确。 #include #include using namespace std; class Person { private: string m_strName; int m_nAge; public: Person(string name,int age) { m_strName=name; m_nAge = age; cout<<"constructor of person"< } ~Person(){ cout<<"deconstrutor of person"< class Employee : public Person { private: string m_strDept; Person Wang; public: Employee (string name, int age, string dept, string name1, int age1) : Person(name,age) , Wang(name1,age1) { m_strDept = dept; cout<<"constructor of Employee"< } ~Employee(){ cout<<"deconstrucor of Employee"< } void main() { Employee emp1; } (3)类的组合 先阅读下面的程序,写出程序执行结果,然后再上机运行,验证自己分析的结果是否正确。 #include #include using namespace std; class A{ public: A(int a,int b):x(a),y(b){ cout<<"A constructor..."< void display(){ cout<<"("< ~A(){cout<<"destructor A..."< private: int x,y; }; class B:private A{ private: int i,j; A Aobj; public: B(int a,int b,int c,int d):A(a,b),i(c),j(d),Aobj(1,1){ cout<<"B constructor..."< void Add(int x1,int y1,int x2,int y2) { A::Add(x1,y1); i=i+x2; j=j+y2; } void display(){ A::display(); Aobj.display(); cout<<"("< } ~B(){cout<<"destructor B..."< }; int main() { B b(1,2,3,4); b.display(); b.Add(1,3,5,7); b.display(); return 0; } (4)编写一个学生和教师的数据输入和显示程序。学生数据有编号、姓名、性别、年龄、系别和成绩,教师数据有编号、姓名、性别、年龄、职称和部门。要求将编号、姓名、性别、年龄的输入和显示设计成一个类Person,作为学生类Student和教师类Teacher的基类。 供参考的类结构如下: class Person{ ... }; class Student:public Person{ ... }; class Teacher:public Person{ ... }; (1)继承访问权限 #include using namespace std; class Base { public: void setx(int i){ x=i;} int getx(){return x;} public: int x; }; class Derived: public Base { public: void sety(int i){ y=i; } int gety(){return y;} void show(){ cout<<”Base::x=”< public: int y; }; int main() { Derived bb; bb.setx(16); bb.sety(25); bb.show(); cout<<”Base::x=”< cout<<”Derived::y=”< cout<<”Base::x=”< cout<<”Derived::y=”< return 0; } 写出程序的运行结果。 按以下要求,对程序进行修改后再调试,指出调试中出错的原因。 ①将基类Base中数据成员x的访问权限改为private时,会出现哪些错误?为什么? ②将基类Base中数据成员x的访问权限改为protected时,会出现哪些 错误?为什么? ③在源程序的基础上,将派生类Derived的继承方式改为private时,会出现哪些错误?为什么? ④在源程序的基础上,将派生类Derived的继承方式改为protected时,会出现哪些错误?为什么? 运行结果 调试中出错的原因 ①将基类Base中数据成员x的访问权限改为private时,出现错误“error C2248: 'x' : cannot access private member declared in class 'Base'”。在公有继承中,内部访问和对象访问均不能访问基类Base的私有成员x。 ②将基类Base中数据成员x的访问权限改为protected时,出现错误“error C2248: 'x' : cannot access private member declared in class 'Base'”。在公有继承中,对象访问不能访问基类Base的保护成员x。 ③在源程序的基础上,将派生类Derived的继承方式改为private时,出现错误“error C2248: 'x' : cannot access private member declared in class 'Base'”。在私有继承中,对象访问不能访问基类Base的公有成员x,setx(int i),getx( )。 ④在源程序的基础上,将派生类Derived的继承方式改为protected时,出现错 误“error C2248: 'x' : cannot access private member declared in class 'Base'”。在保护继承中,对象访问不能访问基类Base的公有成员x,setx(int i),getx( )。 (2) 派生类对象构造过程 先阅读下面的程序,写出程序执行结果,然后再上机运行,验证自己分析的结果是否正确。 #include #include using namespace std; class Person { private: string m_strName; int m_nAge; public: Person(string name,int age) { m_strName=name; m_nAge = age; cout<<"constructor of person"< } ~Person(){ cout<<"deconstrutor of person"< class Employee : public Person { private: string m_strDept; Person Wang; public: Employee (string name, int age, string dept, string name1, int age1) : Person(name,age) , Wang(name1,age1) { m_strDept = dept; cout<<"constructor of Employee"< } ~Employee(){ cout<<"deconstrucor of Employee"< } void main() { Employee emp1; } 运行结果: constructor of person张三 constructor of person王五 constructor of Employee deconstrucor of Employee deconstrutor of person王五 deconstrutor of person张三 (3)类的组合 先阅读下面的程序,写出程序执行结果,然后再上机运行,验证自己分析的结果是否正确。 #include #include using namespace std; class A{ public: A(int a,int b):x(a),y(b){ cout<<"A constructor..."< void display(){ cout<<"("< ~A(){cout<<"destructor A..."< private: int x,y; }; class B:private A{ private: int i,j; A Aobj; public: B(int a,int b,int c,int d):A(a,b),i(c),j(d),Aobj(1,1){ cout<<"B constructor..."< void Add(int x1,int y1,int x2,int y2) { A::Add(x1,y1); i=i+x2; j=j+y2; } void display(){ A::display(); Aobj.display(); cout<<"("< } ~B(){cout<<"destructor B..."< }; int main() { B b(1,2,3,4); b.display(); b.Add(1,3,5,7); b.display(); return 0; } (4)编写一个学生和教师的数据输入和显示程序。学生数据有编号、姓名、性别、年龄、系别和成绩,教师数据有编号、姓名、性别、年龄、职称和部门。要求将编号、姓名、性别、年龄的输入和显示设计成一个类Person,作为学生类Student和教师类Teacher的基类。 #include #include using namespace std; class Person{ public: Person(int no1,string name1,string sex1,int age1) { no=no1;name=name1;sex=sex1;age=age1;} void display() {cout<<”编号:”< cout<<”姓名:”< cout<<”性别:”< cout<<”年龄:”< } protected: int no; string name; string sex; int age; }; plass Student:public virtual Person{ public: Student(int no1,string name1,string sex1,int age1,string depa1,int degree1) :Person(no1,name1,sex1,age1) { depa=depa1; degree=degree1; } void display() {Person::display(); cout<<”系别:”< cout<<”成绩:”< } protected: string depa; int degree; }; class Teacher:public virtual Person { public: Teacher(int no1,string name1,string sex1,int age1,string title1,string depart1) :Person(no1,name1,sex1,age1) {title=title1; depart=depart1; } void display() {Person::display(); cout<<”职称”< cout<<”部门:”< } protected: string title; string depart; }; int main() { Student stu(10001,”张大民”,”男”, 18,”经管系“,95); Teacher tea (15001,”李小敏”,”女”, 48,“副教授”, “自动化学院”); cout<<”学生的有关数据如下:”< std.display(); cout<<”教师的有关数据如下:”< tea.display(); return 0; }