自考2019版《C++程序设计》04747,第五章类的继承与派生(附课后习题答案)

本文详细介绍了类的继承与派生的概念,包括继承的基本原理、不同类型的继承方式及其特点,派生类的构造函数与析构函数的执行顺序,并讨论了类之间的关系如封闭类等。

考试题型:主要在选择题、填空题、程序填充题、程序分析题、程序设计题,比分占20%左右。

第一节 类的继承与派生

1、通过已有的类来建立新类的过程,叫做“类的派生”,原来的类叫做“基类”,新建立的类则叫做“派生类”。

另一方面,从类的成员角度看,派生类自动地将基类的所有成员作为自己的成员,这叫做“继承”。基类和派生类又可以分别叫做“父类”和“子类”,有时也称为“一般类”和“特殊类”。

从一个或多个以前定义的类(基类)产生新类的过程叫做派生,这个新类称为派生类。派生的新类同事也可以增加或者重新定义数据和操作,这就产生了类的层次性。

类的继承是指派生类继承基类的数据成员和成员函数。继承常用来表示类属关系,不能将继承理解为构成关系。

使用基类派生新类时,除构造函数和析构函数外,基类的所有成员自动称为派生类的成员。

2、派生类中定义了与基类同名的成员或成员函数时,在派生类对象访问这个函数式,访问的是派生类的,这种现象叫“覆盖”,也叫重写,也叫同名隐藏,既隐蔽了基本的同名函数。

3、派生类的定义格式如下:

class 派生类名:继承方式  基类名{

派生类新定义成员;

}

派生类访问基类的成员:基类名::基类成员

“继承方式”关键字有:public、protected和private。

4、继承关系的特殊性:派生类不能继承基类的友元函数,但基类的成员函数是其他类的友元函数时,是可以被继承的。

5、继承关系的类之间的访问:派生类中的成员函数可以访问基类中的公有成员和保护成员(非私有成员)。

6、如果基类种的成员是静态的,则在其派生类中,被继承的成员也是静态的,即其静态属性随静态成员被继承。

如果基类的静态成员是公有的或是保护的,则它们被其派生类继承为派生类的静态成员。访问这些成员是,通常用“<类名>::<成员名>”的方式引用或调用。无论有多少个对象被创建,这些成员都只有一个拷贝,它为基类和派生类的所有对象所共享。

派生类的构造函数都会先自动调用父类的构造函数。

7、单重继承:从一个基类派生一个派生类

多重继承:一个派生类同时有多个基类

格式如下:

class 派生类名:继承方式说明符 基类名1,继承方式说明符 基类名2,~

{类体};


第二节 访问控制

1、公有继承public:访问权限保持不变,派生类得到了基类中除构造函数、析构函数之外的所有成员。

类型兼容规则:

(1)派生类的对象可以赋值给基类对象;

(2)派生类的对象可以用来初始化基类的引用;

(3)派生类对象的地址(指针)可以赋值给基类指针。

2、私有继承private:基类中的公有成员和保护成员都以私有成员身份出现在派生类中,在派生类的成员函数可以直接访问它们。

3、保护继承protected:基类中的公有成员和保护成员都以保护成员的身份出现在派生类中,而基类中的私有成员不可访问。

注意:静态成员可以被继承,这时,基类对象和派生类的对象共享改静态成员。


第三节 派生类的构造函数和析构函数

1在执行一个派生类的构造函数之前,总是先执行基类的构造函数。派生类对象消亡时,先执行派生类的析构函数,再执行基类的析构函数。

定义派生类的构造函数一般形式如下:

派生类名::派生类名(参数表0):基类名(参数表)

{...//函数体}

冒号后“基类名(参数表)”称为成员初始化列表,参数给出调用的基类构造函数所需要的实参。实参的值可以来自“参数表0”,或由表达式给出。

构造函数(包括析构函数)是不能被继承的,所以一个派生类只能调用它的直接基类的构造函数。

2、派生类构造函数执行的一般次序如下:

(1)调用基类构造函数,调用顺序按照他们被继承时声明的顺序(从左向右)

(2)对派生类新增的成员变量初始化,调用顺序按照它们在类中声明的顺序。

(3)执行派生类的构造函数中的内容。

程序执行完毕,对象消亡时,需要调用析构函数,先调用派生类的析构函数,后调用基类的析构函数。

3、复制构造函数

复制构造函数:

对于一个类,如果程序中没有定义复制构造函数,则编译器会自动生成一个隐含的复制构造函数,这个隐含的复制构造函数会自动调用基类的复制构造函数,对派生类新增的成员对象一一执行复制。

4、多继承规定派生类包含多个基类时,构造函数的调用顺序是:先调用所有基类的构造函数,再调用对象成员的构造函数(如果有对象成员),最后调用派生类自己的构造函数。对象消亡时,按照构造函数的次序逆调用析构函数。

处于同一继承层次的各基类构造函数的调用顺序取决于定义派生类时所制定的基类的顺序,与派生类构造函数中所定义的成员初始化列表顺序无关。

如果类中有对象成员,那么对象成员构造函数的调用顺序与对象在类中声明的顺序一致。


第四节 类之间的关系

1、使用已有类编写新的类有两种方式:继承和组合。

继承关系也称为“ is a ” 或 “是” 关系,继承关系具有传递性。

组合关系也称为“ has a” 或 “有” 关系,表示包含关系(封闭类)。

2、封闭类

如果一个类的成员变量是另一个类的对象,则为封闭类。

定义封闭类构造函数的一般形式为:

类名: :类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表),~

{类体}

*在派生类也是封闭类的情况下,构造函数的初始化列表不但要指明基类对象的初始化方式,还要指明成员的初始化方式。


第五节 多层次的派生

处于同一继承层次的各基类构造函数的调用顺序取决于定义派生类时所指定的基类的顺序,与派生类构造函数中所定义的成员初始化列表顺序无关。

如果类中有对象成员,那么对象成员构造函数的调用顺序与对象在类中声明的顺序一致。 


第六节 基类与派生类指针的相互转换

公有派生类的对象可以当做基类对象使用,反之则是禁止的,具体表现在:

一个公有派生类的对象的地址可以直接赋值给一个基类指针,使基类指针指向派生类的对象。

一个公有派生类对象可以初始化一个基类引用;

派生类对象可以赋值给一个基类对象;

基类的指针可以指向派生类的对象,但是它只能访问派生类中从基类继承过来的成员,无法访问派生类自有成员。

当派生类指针指向基类对象时,必须要将基类对象进行强制类型转换。


课后习题答案:

一、选择题

1-5、BBACB  6-10、ACBAC  11、C

二、填空题

(1)成员变量  (2)不可访问  (3)派生  (4)继承方式  (5)构造函数和析构函数

(6)多重继承  (7)从基类继承的成员  (8)强制类型转换 

(9)pDerived = (CDerived *)objBase  (10)基类构造函数

三、程序填空题

1、

pDerived->Print()
pBase->Print()

2、

base(sa)

3、

B(int a)
{
    data = a;
    cout<<"带1个参数的构造函数"<<endl;
}

四、程序分析题

2、

Base 默认构造函数
D_Base 默认构造函数
D_Base 析构函数
Base 析构函数
Base 带2个参数的构造函数
D_Base 带3个参数的构造函数
D_Base 析构函数
Base 析构函数

3、

2018/7/16
12:30:0
2018/7/16
12:30:0

4、

CB::b=4
CC::c=6
CD::d=2
CD 的对象在消亡
CC 的对象在消亡
CB 的对象在消亡

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuuuuuuling

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值