Visual C++面向对象程序设计教程与实验(第二版)清华大学出版社

更新时间:2024-04-07 02:35:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1. 什么是类的继承与派生?

继承性是面向对象程序设计的第二个重要特性,通过继承实现了数据抽象基础上

的代码重用。继承是对许多问题中分层特性的一种自然描述,因而也是类的具体化和被重新利用的一种手段,它所表达的就是一种对象类之间的相交关系。它使得某类对象可以继承另外一类对象的特征和能力。继承所具有的作用有两个方面:一方面可以减少代码冗余;另一方面可以通过协调性来减少相互之间的接口和界面。通过继承方式定义的子类也称为派生类。

2. 类的三种继承方式之间的区别是什么?

类的继承方式有public(公有)继承、protected(保护)继承和private(私有)继承三种。对于不同的继承方式,会导致基类成员原来的访问属性在派生类中有所变化。表5.1列出了不同继承方式下基类成员访问属性的变化情况。

表5.1 不同继承方式下基类成员的访问属性

访问属性 继承方式 public protected private public public protected private protected protected protected private private 不可访问的 不可访问的 不可访问的 说明:

该表第1列给出3种继承方式,第1行给出基类成员的3种访问属性。其余单元格内容为基类成员在派生类中的访问属性。

从表中可以看出:

(1) 基类的私有成员在派生类中均是不可访问的,它只能由基类的成员访问。 (2) 在公有继承方式下,基类中的公有成员和保护成员在派生类中的访问属性不变。 (3) 在保护继承方式下,基类中的公有成员和保护成员在派生类中均为保护的。 (4) 在私有继承方式下,基类中的公有成员和保护成员在派生类中均为私有的。 需要注意的是:

保护成员与私有成员唯一的不同是当发生派生后,处在基类protected区的成员可被派生类直接访问,而私有成员在派生类中是不可访问的。在同一类中私有成员和保护成员的用法完全一样。

3. 派生类能否直接访问基类的私有成员?若否,应如何实现?

派生类不能直接访问基类的私有成员。

具体实现方式:(1) 在类定义体中增加保护段

为了便于派生类的访问,可以将基类私有成员中需提供给派生类访问的部分定义为保护段成员。保护段成员可以被它的派生类访问,但是对于外界是隐藏起来的。这样,既方便了派生类的访问,又禁止外界对它的派生类访问。

这种方式的缺点是在公有派生的情况下,如果把成员设为保护访问控制,则为外界访问基类的保护段成员提供了机会,而三种派生方式,我们经常使用的是公有派生。

(2) 将需访问基类私有成员的派生类成员函数声明为基类的友元

这样派生类中的其它成员函数均无权访问它,外界不可能通过派生新类来达到访问基类私有成员的目的。

4. 派生类构造函数和析构函数的执行顺序是怎样的?在多继承中,派生类构造函数和析构函数的执行顺序又是怎样的?

构造函数的执行顺序:先祖先(基类)、再客人(对象成员),后自己(派生类本身)。 析构函数的执行顺序和构造函数正好严格相反:先自己(派生类本身),再客人(对象成员),后祖先(基类)。 在多个基类之间严格按照派生类定义时从左到右的顺序来排列先后。而析构函数的调用顺序刚好与构造函数的相反。

5. 派生类的构造函数和析构函数的作用是什么?

在下面两种情况下,必须定义派生类的构造函数:派生类本身需要构造函数;在定义派生类对象时,其相应的基类对象需调用带有参数的构造函数。

派生类对象的初始化也是通过派生类的构造函数实现的。具体来说,就是对该类的数据成员赋初值。

派生类析构函数的功能与没有继承关系的类中析构函数的功能一样,也是在对象消亡之前进行一些必要的清理工作。

6. 多继承一般应用在哪些场合?

对于多重继承,派生类可以有多个直接基类。这时的派生类同时得到了多个已有类的特征。

7. 在类的派生中为何引入虚基类?在含有虚基类的派生类中,当创建它的对象时,构造函数的执行顺序如何?

当在多条继承路径上有一个公共的基类,在这些路径中的某几条路径汇合处,这个公共的基类就会产生多个实例(或多个副本),若想只保存这个基类的一个实例,可以将这个公共基类说明为虚基类。从基类派生新类时,使用关键字virtual可以将基类说明成虚基类。

在多个基类之间严格按照派生类定义时从左到右的顺序来排列先后。而析构函数的调用顺序刚好与构造函数的相反。如果基类中有虚基类,则构造函数的调用顺序采用下列规则:

(1) 虚基类的构造函数在非虚基类之前调用。

(2) 若同一层次中包含多个虚基类,这些虚基类的构造函数按照他们说明的次序调用;

(3) 若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。

特别需要注意,当一个派生类同时有多个基类时,对于所有需要给予参数进行初始化的基类,都要显式给出基类名和参数表。对于使用默认构造函数的基类,可以不给出类名。同样,对于对象成员,如果是使用默认构造函数,也不需要写出对象名和参数表。而对于单继承,就只需要写一个基类名就可以了。

8. 设计一个大学的类系统,学校中有学生、教师、职员,每种人员都有自己的特性,他们之间又有相同的地方。利用继承机制定义这个系统中的各个类及类上必须的操作。

参考程序:

#include #include

class Person{ protected:

char m_strName[10]; int m_nSex; int m_nAge;

public: Person(char *name,int age,char sex){

int getAge(){

strcpy(m_strName, name); m_nSex= (sex=='m'?0:1 ); m_nAge = age;

}

void setName(char *name){ strcpy(m_strName, name); }

void setSex(int sex){ m_nSex= (sex=='m'?0:1 ); }

void setAge(int age){ m_nAge = age; }

char * getName(){ return m_strName; }

};

return m_nAge; }

int getSex(){ return m_nSex; }

void ShowMe(){

cout<<\姓 名:\

cout<<\性 别:\男\女\cout<<\年 龄:\}

class Teacher : public Person{ char m_strDept[20]; int m_fSalary;

public: Teacher(char *name,int age,char sex,char *dept,int salary) };

class Student : public Person{

void setSalary(int salary){ m_fSalary = salary; }

int getSalary(){ return m_fSalary; }

:Person(name,age,sex){ strcpy(m_strDept, dept); m_fSalary = salary; }

void ShowMe() {

Person::ShowMe();

cout<<\工作单位:\cout<<\月 薪:\}

public: };

char m_strID[12]; char m_strClass[12];

Student(char *name,int age,char sex,char *ID,char *Class) :Person(name,age,sex){ strcpy(m_strID, ID);

strcpy(m_strClass, Class); }

void ShowMe(){

cout<<\学 号:\Person::ShowMe();

cout<<\班 级:\}

void setID(char * ID){ strcpy(m_strID, ID); }

void setClass(char *Class){ strcpy(m_strClass, Class); }

char* getID(){ return m_strID; }

char* getClass(){ return m_strClass; }

class Employee:public Person{ int m_fSalary; public:

Employee(char *name,int age,char sex,int salary) :Person(name,age,sex){ m_fSalary = salary; }

};

void setSalary(int salary){ m_fSalary = salary; }

int getSalary(){ return m_fSalary; }

void ShowMe(){ Person::ShowMe();

cout<<\工 资:\}

void main(){ // 定义三个不同类的对象

//修改各类人员的属性 teacher1.setAge(40); teacher1.setSalary(4500); std1.setAge(21); emPloyee1.setAge(26); emPloyee1.setSalary(2000);

cout<<\cout<<\修改各类人员的属性后:\teacher1.ShowMe();

cout<<\std1.ShowMe();

Teacher teacher1(\刘馨\计算机系\Student std1(\刘丽\计算机03\Employee emPloyee1(\张鑫\

//显示各类人员的属性

teacher1.ShowMe();

cout<<\std1.ShowMe();

cout<<\emPloyee1.ShowMe();

}

cout<<\emPloyee1.ShowMe();

程序的执行结果为:

姓 名:刘馨

性 别:男 年 龄:38

工作单位:计算机系 月 薪:3800

------------------- 学 号:03016003 姓 名:刘丽 性 别:女 年 龄:20 班 级:计算机03 ------------------- 姓 名:张鑫 性 别:女 年 龄:25

工 资:1500

------------------- 修改各类人员的属性后: 姓 名:刘馨 性 别:男 年 龄:40 工作单位:计算机系 月 薪:4500 ------------------- 学 号:03016003 姓 名:刘丽 性 别:女 年 龄:21 班 级:计算机03 ------------------- 姓 名:张鑫 性 别:女 年 龄:26 工 资:2000

9. 假定车可分为货车和客车,客车又可分为轿车、面包车和公共汽车。请设计相应的类层次结构。

说明:可以把轿车、面包车和公共汽车定义为客车类的对象 参考程序:

#include using namespace std;

class vehicle {

public:

// 定义基类vehicle // 公有函数成员

vehicle(int in_wheels,float in_weight); // 给数据成员初始化 int get_wheels(); // 获取车轮数 float get_weight(); // 获取汽车重量 void setWeels(int wls);

void setWeight(float wt); void display(){ cout<<\车轮数:\

<<\ 汽车重量:\ }

private: // 私有数据成员 int wheels; // 车轮数

float weight; // 表示汽车承重 };

vehicle::vehicle(int in_wheels,float in_weight){ }

float vehicle::get_weight(){ }

int vehicle::get_wheels(){ return wheels; }

void vehicle::setWeels(int wls){ }

wheels = wls; return weight; wheels = in_wheels; weight = in_weight;

void vehicle::setWeight(float wt){

weight = wt;

}

class truck:public vehicle // 定义货车类truck {

private: // 新增私有数据成员 float weight_load; // 承重

public: // 新增公有成员函数 truck(int wheel,float wt,float wl):vehicle(wheel,wt){ weight_load = wl; }

float getLoads(){ return weight_load; }

void display(){ } };

//车和客车,客车又可分为轿车、面包车和公共汽车 class car:public vehicle // 定义客车类car {

int passenger_load; public:

void setPassengers(int people){

// 新增私有数据成员,表示载客数

// 新增公有成员函数

vehicle::display();

cout<<\汽车承重\

car(int in_wheels,float in_weight,int people=4):vehicle(in_wheels,in_weight) {

passenger_load = people; }

int getPassengers(){ return passenger_load; }

};

passenger_load = people; }

void display(){

vehicle::display();

cout<<\载客数:\}

void main(){ truck truck1(8,400,100000);

car car1(4,20);

car saloon_car(4,10,5); car microbus(6,10,18); car bus(6,20,30); // 显示相关信息 truck1.display();

cout<<\car1.display();

cout<<\saloon_car.display();

cout<<\microbus.display();

cout<<\bus.display();

// 货车 // 客车 // 轿车 // 面包车 // 公共汽车

}

程序的运行结果: 车轮数:8 汽车重量:400 汽车承重100000 ---------------------

车轮数:4 汽车重量:20 载客数:4

---------------------

车轮数:4 汽车重量:10 载客数:5

---------------------

车轮数:6 汽车重量:10

int m_nAge; public:

char * getName(){ }

return m_strName;

Person(char *name,int age,char sex){ } }

void setSex(int sex){ m_nSex= (sex=='m'?0:1 ); }

void setAge(int age){ m_nAge = age; }

strcpy(m_strName, name);

m_nSex= (sex=='m'?0:1 ); m_nAge = age;

void setName(char *name){

strcpy(m_strName, name);

int getAge(){ }

int getSex(){ }

void ShowMe(){ cout<<\ 姓 名:\

cout<<\ 性 别:\男\女\cout<<\ 年 龄:\return m_nSex; return m_nAge;

} };

class Teacher : public Person{

char m_strDept[20];

int m_fSalary; public: };

class Student : public Person{

char m_strID[12]; char m_strClass[12]; char * getDept(){ }

int getSalary(){ return m_fSalary; }

return m_strDept; void setSalary(int salary){ m_fSalary = salary; }

void ShowMe() { }

Person::ShowMe();

cout<<\ 工作单位:\cout<<\ 月 薪:\Teacher(char *name,int age,char sex,char *dept,int salary)

:Person(name,age,sex){ strcpy(m_strDept, dept);

m_fSalary = salary; }

public: Student(char *name,int age,char sex,char *ID,char *Class)

:Person(name,age,sex){ strcpy(m_strID, ID);

strcpy(m_strClass, Class); }

void ShowMe(){ cout<<\ 学 号:\

Person::ShowMe();

};

}

cout<<\ 班 级:\

void setID(char * ID){ strcpy(m_strID, ID); }

void setClass(char *Class){ strcpy(m_strClass, Class); }

char* getID(){ return m_strID; }

char* getClass(){ return m_strClass; }

class Master:public Student, public Teacher{

public: Master(char *name,int age,char sex,char *ID,char *Class,char *dept,int salary) };

void main(){ // 定义三个不同类的对象 Teacher teacher1(\刘馨\计算机系\ Student std1(\刘丽\计算机03\

Master master(\张鑫\机械052\机械系\ }

void ShowMe(){

}

Student::ShowMe();

cout<<\ 工作单位:\cout<<\ 月 薪:\

:Student(name,age,sex,ID,Class),Teacher(name, age, sex, dept, salary){

}

//显示各类人员的属性 teacher1.ShowMe();

cout<<\std1.ShowMe();

cout<<\master.ShowMe();

程序的运行结果为: 姓 名:刘馨 性 别:男 年 龄:38

工作单位:计算机系 月 薪:3800 --------------------

学 号:03016003 姓 名:刘丽 性 别:女 年 龄:20 班 级:计算机03 -------------------- 学 号:003 姓 名:张鑫 性 别:女 年 龄:25 班 级:机械052 工作单位:机械系 月 薪:1000

本文来源:https://www.bwwdw.com/article/m0ar.html

Top