当前位置:文档之家› C课件 第9章 继承

C课件 第9章 继承

C课件 第9章 继承
C课件 第9章 继承

---------------------------------------------------------------最新资料推荐------------------------------------------------------

C课件第9章继承

第九章面向对象 1--继承这一章的内容包括:

基类和派生类派生类的构造函数/析构函数子类型化和类型适应多继承虚基类一、基类和派生类1.概念通过继承机制,可以利用已有的数据类型来定义新的数据类型。

所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。

我们称已存在的用来派生新类的类为基类,又称为父类。

由已存在的类派生出的新类称为派生类,又称为子类。

在 C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。

从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

2.语法单继承的定义格式如下:

class 派生类名: 继承方式基类名 { //派生类新定义成员 }; 其中,派生类名是新定义的一个类的名字,它是从基类名中派生的,并且按指定的继承方式派生的。

继承方式常使用如下三种关键字给予表示:

public 表示公有基类; private 表示私有基类;protected 表示保护基类;示例:

1 / 13

class MyDate: public Date1 { //派生类新定义成员变量或函数 }; //派生类新定义成员变量(或函数)初始化(或实现) 3 派生类的三种继承方式公有继承(public)、私有继承(private)、保护继承(protected)是三种继承方式。

(1) 公有继承(public) 公有继承的特点是基类的private、 public 和protected 成员作为派生类的成员时,它们都保持原有的状态。

(2) 私有继承(private) 私有继承的特点是基类的 public 成员和 protected成员,在派生类都变为私有成员。

基类的原私有成员仍为派生类的私有成员 (3) 保护继承(protected) 保护继承的特点是基类的public 成员和protected成员,在派生类都变为保护成员。

基类的原私有成员仍为派生类的私有成员。

下表列出三种不同的继承方式的基类特性和派生类特性:

继承方式基类成员派生类成员公有继承public protected private public protected private 私有继承 public protected private 变为 private 变为 private private 保护继承public protected private 变为 protected protected private 对于单级继承来说,讨论保护继承与私有继承的区别意义是不大的,他们的区别只在多级继承的情况中体现。

私有继承在一些特定场合下可用于表示类的组成关系。

保护继承与私有继承在实际编程中是极其少见的。

---------------------------------------------------------------最新资料推荐------------------------------------------------------ Q1:

C++默认的继承方式?对于 C++的类(class),默认的继承方式是私有继承(private),而最常用的继承方式是公有继承(public)。

对于C++的结构体(struct) 默认的继承方式是公有继承(public)。

4.基类与派生类的关系任何一个类都可以派生出一个新类,派生类也可以再派生出新类,因此,基类和派生类是相对而言的。

基类与派生类之间的关系可以有如下几种描述,了解这些关系有助于指导实际编程工作:

( 1)派生类是基类的具体化类的层次通常反映了客观世界中某种真实的模型。

在这种情况下,不难看出:

基类是对若干个派生类的抽象,而派生类是基类的具体化。

基类抽取了它的派生类的公共特征,而派生类通过增加行为将抽象类变为某种有用的类型。

( 2)派生类是基类定义的延续先定义一个抽象基类,该基类中有些操作并未实现。

然后定义非抽象的派生类,实现抽象基类中定义的操作。

例如,虚函数就属此类情况。

3 / 13

这时,派生类是抽象的基类的实现,即可看成是基类定义的延续。

这也是派生类的一种常用方法。

( 3)派生类是基类的组合在多继承时,一个派生类有多于一个的基类,这时派生类将是所有基类行为的组合。

比如以前讲过的飞机组成的例子,用组成关系和多继承都可以,但最好使用组成关系。

派生类将其本身与基类区别开来的方法是添加数据成员和成员函数。

因此,继承的机制将使得在创建新类时,只需说明新类与已有类的区别,从而大量原有的程序代码都可以复用,所以有人称类是可复用的软件构件。

在实际编程中,一定要注意,继承是软件体系结构方面的问题:

( 1)派生类最好是基类的一类(is a kind of),否则容易出现设计概念错误。

(2)继承会增加空间复杂度和时间复杂度,要慎重使用。

继承链不要太长(3-5 层足矣),要头轻脚重,越是顶层的类越要轻巧----最好是完全抽象的虚类。

(3)优先使用组成关系(有的书叫聚集、聚合、复合),而不是继承关系解决问题。

继承把抽象化角色(基类)和实现化角色(派生类)的关系

---------------------------------------------------------------最新资料推荐------------------------------------------------------ 绑定,使得两个层次之间产生了相互依赖和限制,很难独立地演化,在软件设计中应避免此类问题。

组成关系没有这个缺点。

(4)基类要坚固不变,否则派生类。

如果基类的变化是必需的,那应该在派生类和基类之间加一个设计概念上更抽象的第三者类,用这个第三者的类去破坏原有的继承关系。

想想为什么数据库访问要通过 JDBC 等接口。

Q2:

实际编程中使用继承应注意哪些问题?要求对课件讲到的做1 -2 点补充。

Q3:

你对优先使用组成关系,而不是继承关系是怎样理解的?要有自已的观点。

二.派生类的构造函数/析构函数当一个派生类被实例化时,其基类也被实例化,实际上一个派生类对象是由其基类对象和派生类对象组装而成,了解这一点才能了解派生类构造函数/析构函数的有关特性。

1. 派生类的构造函数构造函数不能够被继承,因此,派生类的构造函数必须通过调用基类的构造函数来初始化派生类对象。

所以,在定义派生类的构造函数时除了对自己的数据成员进

5 / 13

行初始化外,还必须负责调用基类构造函数使基类数据成员得以初始化。

如果派生类中还有子对象时(比如将某个类的对象作为派生类的成员变量),还应包含对子对象初始化的构造函数。

派生类构造函数的一般格式如下:

派生类名(派生类构造函数总参数表):基类构造函数(参数表 1),子对象名(参数表 2) { //派生类中数据成员初始化 }; 派生类构造函数的调用顺序如下:

基类的构造函数子对象类的构造函数(如果有的话派生类构造函数例:

class A{ private: int a; public: A() { a=0; } //缺省构造函数A(int i) { a=i; } //构造函数~A() { } //类 A 的析构函数 } class B : public A{ private: int b; A aa; //子对象 aa public: B() { b=0;} //类 B 的缺省构造函数 B(int i, int j, int k); //构造函数 ~B() { }//类 B 的析构函数 } //类 B 构造函数,注意顺序 B::B(int i, int j, int k) : A(i) , aa(j) {b=k;} 派生类构造函数使用中应注意的问题 (1) 派生类构造函数的定义中可以省略对基类构造函数的调用,其条件是在基类中必须有缺省的构造函数或者根本没有定义构造函数。

(2) 当基类的构造函数使用一个或多个参数时,则派生类必须定义构造函数,提供将参数传递给基类构造函数途径。

---------------------------------------------------------------最新资料推荐------------------------------------------------------ 在有的情况下,派生类构造函数的函数体可能为空,仅起到参数传递作用。

2. 派生类的析构函数当派生类对象被删除时,派生类的析构函数被执行。

执行顺序与执行构造函数时的顺序正好相反。

三、子类型化和类型适应这一小节要掌握两个概念:

子类型化和类型适应。

这两个概念在软件设计书籍中常见。

1. 子类型化有一个特定的类型 S,当且仅当它至少提供了类型 T 的行为,由称类型 S 是类型 T 的子类型。

或者说类型 T 是类型 S 的子集。

子类型主要存在于类的继承关系,但不仅限于继承关系。

在 C++继承中,公有继承可以实现子类型。

例如:

class A{ public: void p() { } }; class B : public A{ public: void f() {} }; 类 B 继承了类 A,并且是公有继承方式。

因此,可以说类 B 是类 A 的一个子类型,类 B 具备类 A 中的所有行为,或者说类 A 中的所有行为可被用于类 B。

子类型关系是不可逆的。

7 / 13

这就是说,已知 B 是 A 的子类型,而认为 A 也是 B 的子类型是错误的,或者说,子类型关系是不对称的。

2. 类型适应回顾 JAVA 语言, JAVA 语言的继承性都是 public 的(实际上 JAVA 语言也不允许 private 和 protected 继承),也就是说JAVA 语言的子类都是父类的子类型。

JAVA 课本 P89类的赋值相容性中有一句话:

子类对象即是父类对象,说的就是子类型和类型适应问题。

类型适应是指两种类型之间的关系。

例如, B 类型适应 A类型是指 B 类型的对象能够用于 A 类型的对象所能使用的场合。

或者说,可以将子类对象赋值给父类对象,反过来则不可以。

派生类的对象可以用于基类对象所能使用的场合,我们说派生类适应于基类。

同样道理,派生类对象的指针和引用也适应于基类对象的指针和引用。

子类型化与类型适应是一致的。

A 类型是

B 类型的子类型,那么 A 类型必将适应于 B 类型。 Q4:

理解子类型和类型适应的概念四、多继承 1.语法从多个基类派生的继承称为多继承。

多继承的定义格式如下:

class 派生类名:继承方式 1 基类名 1, 继承方式 2 基类

---------------------------------------------------------------最新资料推荐------------------------------------------------------ 名 2, { //派生类新定义成员 }; 示例:

class MyDate: public Date1,protected Date2 { //派生类新定义成员变量或函数 }; //派生类新定义成员变量初始化或函数实现 2.多继承的构造函数在多继承的情况下,派生类的构造函数格式如下:

派生类名( 总参数表) :基类名 1 ( 参数表 1 ) , 基类名 2 ( 参数表 2 ) , 子对象名( 参数表 n + 1 ) , { / / 派生类构造函数体 } 其中,总参数表中各个参数包含了其后的各个分参数表。

多继承下派生类的构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用。

3.多继承的二义性问题一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。

例 1 :

下面举一个的例子,对二义性问题进行讨论:

class A{ public: void f(); } ; class B{ public: void f() ; void g(); } ; class C : public A, public B { public: void g() ; void h() ; } ; 如果实例化一个类 C 的对象 c1 ,则对函数 f()的访问 c1 .f(); 便具有二义性:

9 / 13

是访问类 A 中的 f(),还是访问类 B中的 f()呢?解决的方法可用以前学过的成员名限定法来消除二义性,例如:

c1 .A::f() ; 或者 c1 .B::f() ; 例 2:

下面再举一个的例子,对菱型继承的二义性问题进行讨论,这个问题比较重要:

当一个派生类从多个基类派生类,而这些基类又有一个共同的基类,也就是说菱型继承时,则对该基类中说明的成员进行访问时,也可能会出现二义性。

例如:

class A{ public: int a; } ; class B1 : public A{ private: int b1 ; } ; class B2 : public A{ private: int b2; } ; class C : public B1 , public B2{ public: int f(); private: int c; } ; 当实例化一个 C 类对象 c1 ,内存是什么状况呢?对象 c1 是由 2 个 A 对象, 1 个 B1 对象, 1 个 B2 对象,1 个 C 对象组合而成,这几个对象不一定占用连续的空间,它们彼此用指针或引用关联成一个整体。

为什么会有两个 A 对象?因为 B1 和 B2 各实例化了一个A 对象。

由于有两个 A 对象存在,下面的访问都有二义性:

c1 .a; c1 .A::a; 而下面的访问是正确的:

c1 .B1 ::a; c1 .B2::a; 由于二义性的原因,一个类不可以从同一个类中直接继承一次以上,例如:

---------------------------------------------------------------最新资料推荐------------------------------------------------------

class A : public B, public B { } 这是错误的。

上面的两个例子,消除二义性的解决办法都不算好,有没

有更好的办法?答案是使用虚基类。

五、虚基类 1.虚基类消除二义性再回到前面例

2 的菱型继承问题,由类 A,类 B1 和类B2 以及类 C 组成了类

继承的(菱型)层次结构。

该结构产生二义性的原因是:

类 C 的对象将包含两个类 A 的子对象(类B1 和类 B2 各实例

化出一个类 A 对象)。

如果要想使这个公共基类在派生类中只产生一个基类子对象,

则必须将这个基类设定为虚基类。

实际上,引进虚基类的真正目的就是为了解决二义性问题。

虚基类说明格式如下:

virtual 继承方式基类名其中, virtual 是虚类的关

键字。

虚基类的说明是用在定义派生类时,写在派生类名的后面。

例 3:

class A{ public: void f() ; protected: int a; } ; class B1 : virtual public A { protected: int b; } ; class B2 : virtual public A { protected: int c: } ; class C : public B1, public B2 {public:

11 / 13

int g() ; private: int d; } ; 由于使用了虚基类,当实例化一个 C 类对象 c1 ,内存是什么状况呢?对象 c1 是由 1 个 A 对象, 1 个 B1 对象, 1 个 B2 对象, 1个 C 对象组合而成。

为什么只有一个 A 对象?因为 B1 和 B2 声明 A 为虚基类,保证只产生一个 A 对象, B1 和 B2 各有一个虚基类指针,指向同一个 A 对象。

这样,当实例化了 C 类对象 c 后,内存中只有一个 A 对象,这样消除了可能出现的二义性。

因此,下面的引用都是正确的:

C c; c. f() ; 对 f() 的引用,不必区分是类 B1 或类 B2 实例化的类 A 对象,因为类 A 对象只有一个。

同理,下面两行对 f() 的引用也是正确的。

void C: : g() { f() ; } 2 回想 JAVA 的多继承 JAVA 对多继承的解决办法是简单的:

只允许继承一个实类,允许继承多个接口,而接口是不会被实例化的,这样就避免了因出现多个父类对象而造成的二义性。

3 虚基类的构造函数本章前面讲过,为了初始化基类的子对象,派生类的构造函数要调用基类的构造函数。

对于虚基类来讲,由于派生类的对象中只有一个虚基类子对象,为保证虚基类子对象只被初始化一次,这个虚基类构造函数必

---------------------------------------------------------------最新资料推荐------------------------------------------------------ 须只被调用一次。

由于继承结构的层次可能很深,规定将在建立对象时所指定的类称为最派生类。

C++规定,虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的。

如果一条继承链上有多个派生类调用虚基类的构造函数,编译器保证只能由最派生类调用一次且仅一次。

其它具体规定略去不讲。

4 小结通过对本章三、四小节多继承的二义性讨论,我们看到多继承虽然在思想上更符合现实世界,但带来的编译器设计、程序设计方面的复杂性太多,这也是 JAVA 取消多继承的重要源因。 Q5:

从对象在内存中的映像,理解菱型继承带来的二义性问题。

Q6:

从对象在内存中的映像,理解虚基类怎样消除二义性。

本章课后习题:

Q1-Q6

13 / 13

第3章 继承和派生习题

《面向对象程序设计》习题 班级:学号:姓名:名单序号:成绩: 第3章继承与派生 一、选择题(共28分,每题1分) 1.下列对派生类的描述中,()是错误的。 A.一个派生类可以作为另一个派生类的基类 B.派生类至少有一个基类 C.派生类的成员除了它自己的成员外,还包含了它的基类成员 D.派生类中继承的基类成员的访问权限到派生类保持不变 2.派生类的对象对它的哪一类基类成员是可以访问的?() A.公有继承的基类的公有成员 B. 公有继承的基类的保护成员 C. 公有继承的基类的私有成员 D. 保护继承的基类的公有成员 3.关于多继承二义性的描述,()是错误的。 A.派生类的多个基类中存在同名成员时,派生类对这个成员访问可能出现二义性B.一个派生类是从具有共同的间接基类的两个基类派生来的,派生类对该公共基类的访问可能出现二义性 C.解决二义性最常用的方法是作用域运算符对成员进行限定 D.派生类和它的基类中出现同名函数时,将可能出现二义性 4.多继承派生类构造函数构造对象时,()被最先调用。 A.派生类自己的构造函数B.虚基类的构造函数 C.非虚基类的构造函数D.派生类中子对象类的构造函数 5.C++类体系中,能被派生类继承的是()。 A.构造函数B.虚函数C.析构函数D.友元函数 6.设有基类定义: class Cbase { private: int a; protected: int b; public: int c; }; 派生类采用何种继承方式可以使成员变量b成为自己的私有成员( ) A. 私有继承 B.保护继承 C. 公有继承 D.私有、保护、公有均可 7.C++中的类有两种用法:一种是类的实例化,即生成类对象,并参与系统的运行;另一种是通过()派生了新的类。 A.复用 B.继承 C.封装 D.引用 8.继承具有(),即当基类本身也是某一个类派生类时,底层的派生类也会自动继承间接基类的成员。 A.规律性 B.传递性 C.重复性 D.多样性

C 第八章继承与派生习题习题解答

第八章继承与多态习题 一.基本概念与基础知识自测题 8.1填空题 8.1.1 如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。(3)类 的对象可作为(4)类的对象处理,反过来不行,因为(5)。如果强制转换则要注意(6)。 答案:(1)基类 (2)派生类 (3)派生类 (4)基类 (5)派生类有一些新成员 (6)只能派生类强制转换为基类 8.1.2 当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员, protected成员成为派生类的(2)成员,对private成员是(3)。公有派生可以使其类的(4),所以公有派生是主流。 答案:(1)public成员 (2)protected成员 (3)不可访问 (4)接口不变 8.1.4 一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为 (2)。继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。 答案:(1)单继承 (2)多重继承 (3)层次 (4)单继承 8.1.6 C++中多态性包括两种多态性:(1)和(2)。前者是通过(3)实现的, 而后者是通过(4)和(5)来实现的。 答案:(1)编译时的 (2)运行时的 (3)函数和运算符的重载 (4)类继承关系 (5)虚函数 8.2简答题(以下习题题号可能和教材不一致!) 8.2.1构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎样的?答:构造函数和析构函数不可以继承。派生类构造函数各部分的执行次序是: 1.调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。 2.调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。 3.派生类的构造函数体中的操作。 8.2.2什么叫派生类的同名覆盖(override)?

第七章派生与继承2

第七章派生与继承2 /*7.4多继承与虚基类 7.4.1多继承中的二义性问题 解决方式 1<对象名>.<基类名>::<成员名> //数据成员 <对象名>.<基类名>::<成员名>(<参数名>) //成员函数 */ /*#include using namespace std; class Base1 { public: int date; void fun(){cout<<"Member of Base1"<<";base1="< class A1 { public: void show1() { cout<<"class A1"<

3. 下列描述中哪个是正确的__________。?????? A 私有派生的子类无法访问父类的成员 B 类A的私有派生子类的派生类C无法初始化其祖先类A对象的属性,因为类A的成员对类C是不可访问的 C 私有派生类不能作为基类派生子类 D 私有派生类的所有子孙类将无法继续继承该类的成员 参考答案 B 4. 下面有关派生类的说法中,错误的是( )。 A 一个派生类可以作为另一个派生类的基类 B 一个派生类可以有多个基类 C 派生类构造函数可以将初始化参数值传递给基类的构造函数和对象成员的构造函数 D 具有继承关系时,基类成员在派生类中的访问权限不变 参考答案 D 5. 设置虚基类的目的是( )。 A 简化程序 B 消除二义性 C 提高运行效率 D 减少目标代码 参考答案 B 6. 有以下定义的子类: class A:public B { ... }; 则下面描述中正确的是 A A类中的成员函数可以访问B类中的private 数据成员 B A类中的成员函数只能访问B类中的protected数据成员。 C A类中的成员函数可以访问B类中的public数据成员。 D A类中的成员函数只能访问B类中的public数据成员 参考答案 C 7. 有如下类定义: class A { public: int x; };

第十一章 继承与派生 复习题

第十一章继承与派生复习题 1. 下面叙述错误的是( ) A. 派生类可以使用private派生 B. 对基类成员的访问必须是无二义性的 C. 基类成员的访问能力在派生类中维持不变 D. 赋值兼容规则也适用于多继承的组合 2.派生类的对象对它的基类成员进行访问,可以采用对象.或者对象指针-〉的 方式访问的是( ) A. 公有继承的公有成员 B. 公有继承的私有成员 C. 公有继承的保护成员 D. 私有继承的公有成员 3. 当私有继承时,在派生类中成为私有成员,不能通过派生类的对象来直接访 问该成员是基类的() A. 任何成员 B.公有成员和保护成员 C. 保护成员和私有成员 D.私有成员 4. C++的类有两种用法:一种是类的实例化,即生成类的对象,并参与系统的运 行;另一种是通过() A. 复用派生出新的类 B. 继承派生出新的类 C. 封装派生出新的类 D. 引用派生出新的类 5.当保护继承时,在派生类中成为保护成员,不能通过派生类的对象来直接访 问的成员是基类的() A.任何成员 B.公有成员和保护成员 C.保护成员和私有成员 D.私有成员 6.类B的数据成员中“有一个”A类的对象,这种类之间的关系是( ) A.继承关系 B.间接关系 C.组合关系 D.直接关系 7. 派生类的构造函数的成员初始化列表中,不能包含( ) A. 基类的构造函数 B. 派生类中子对象的初始化 C. 基类中子对象的初始化 D. 派生类中一般数据成员的初始化 8 公有成员提供了类对外部的接口,私有成员是类的内部实现,而不允许外界 访问,但允许派生类访问的成员是( ) A. 公有成员 B. 私有成员 C. 私有成员 D. 保护成员 9. 当公有继承时,在派生类中成为保护成员,不能通过派生类的对象来直接访

实验二 继承与派生 (完整版)

实验二继承和派生的基本概念 一、实验目的 继承与派生是面向对象的特性,是面向对象程序设计模拟客观世界的手段之一,本实验的内容包括介绍基类与派生关系,通过实验要求掌握以下内容。 1.掌握类继承与派生关系以及实现方法,理解类的层次结构。 2.掌握派生类构造函数初始化基类成员和对象成员的方法。 3.掌握赋值兼容原则,掌握派生类的复制构造函数和赋值运算符的定义。 二、实验内容 1.范例:定义一个继承与派生关系的类体系,在派生类中访问基类成员。先定义一个点类,包含x,y坐标数据成员,显示函数和计算面积的函数成员;以点为基类派生一个圆类, 增加表示半径的数据成员,重载显示和计算面积的函数;定义一个线段类,以两个点类对象作数据成员,定义显示、求面积及长度函数,线段类采用聚合方式,因为有两个端点, 不能用派生方式。编程测试所定义的类体系。 【程序】

cl3=cl1; cout<<"cl3圆面积:"<< cl3.Area()<< endl; cl3.Show(); cout<<"线面积:"<< ln1. Area()<<'\t'<<"线长度:"<< ln1. GetLength()<< endl; ln1.Show(); ln2.Show(); return 0; } 【注意】 在Point 类中,将Line 类定义为友元,便于在Line 类中访问;Point 类的x和y 定义为Protected 访问权限,便于派生类访问。

注意派生类的构造函数中对基类数据成员的初始化方法(即 Circle(double xv,double yv,double vv):Point(xv,yv)), 以及构造函数中对对象成员的初始化方法(即 Line(double xv1,double yv1,double xv2,double yv2) : start(xv1,yv1),end(xv2,yv2){ } ) 【要求】 (1)建立工程,录入上述程序,改变数据实验之。 (2)修改Point 类的数据成员x ,y 的访问权限为private ,再运行,结果如何? 在Line类和Circle类中无法访问Point类的私有成员x,y. (3)如果不将Line 类设为 Point 类的友元,应采取什么措施?为哪个类增加数据或函数成员? 2.编程:多层派生练习,由上题Point 类和Circle 类继续派生出Cylinder 类。要求计算圆柱体的底面积、侧面积、全面积和体积。 #include #include using namespace std; const float PI=3.14; class Point {friend class Line; protected: double x,y; public: Point() {x=0;y=0;} Point(double xv,double yv) {x=xv;y=yv;} double Area() {return 0;}

第4章 继承与派生习题 参考答案

第4章继承与派生习题参考答案 一、选择题(共30分,每题1分) 二、填空题(共17分,每空1分) 1. 基类 2. (1)派生类(2)派生类中子对象类(3)基类 3. (1)c1、b2、b3、A2、A3 (2)c2 (3)c3 4. (1)基类 (2)派生类 5. ~A() {cout<<"bb";} 6. A(aa),c(aa+1) 或c(aa+1),A(aa) 7. (1)公有成员(2)公有和保护成员 8. (1)保护(2)成员函数(3)不可访问 三、改错题(共6分,每题2分) 1. 保护继承方式使基类的public成员在派生类中的访问属性变为protected,所以派生类Rectangle的对象r不能直接访问基类的成员函数move()、getx()和gety()。其改正方法有两种: 1)将Rectangle的继承方式改为公有继承class Rectangle: public Point; 2)在Rectangle类中重定义move(),getx()和gety()函数,覆盖基类的同名函数。 void Rectangle::move(intxoffset,intyoffset){Point::move(xoffset,yoffset);} void Rectangle::getx(){return Point::getx();} void Rectangle::gety(){return Point::gety();} 2. 分析:类A、B中有同名公有数据成员x和同名成员函数display(),在主函数中访问对象myc的数据成员x是无法确定是访问从A中继承的还是从B中继承的x;调用成员函数也是如此,无法确认是调用类A中的还是类B中的,产生二义性。 改正方法,可以用作用域区分符加以限定,如改成: myc.A::x=10; myc.A::display(); 或myc.B::x=10; myc.B::display(); 3. #include using namespace std; class Member{

【习题】继承与派生

继承与派生 【实验目的】: 1.掌握派生类的使用方法。 2.掌握派生类的构造函数和析构函数。 【实验内容】: 1.定义一个哺乳动物Mammal类,再由此派生出狗Dog类,定义一个Dog类的对象, 观察基类与派生类的构造函数与析构函数的调用顺序。 2.编写一个求出租车收费的程序,输入起始站、终止站和路程,计费公式是起价8 元,其中含3公里费用,以后每半公里收费0.7元。

生类Student和教师类Teacher,并用一些数据进行测试。 4.定义一个rectangle类,它包含两个数据成员length和width;以及包含用于求长方 形面积的成员函数。再定义rectangle的派生类cuboid,它包含一个新数据成员height和用来求长方体体积的成员函数。在主函数中,使用2个类,求某个长方形 的面积和某个长方体的体积。

5.声明一个Object类,有数据成员weight和相应的操作函数,由此派生出的Box类, 增加数据成员height和weight及相应的操作函数,声明一个Box对象,观察构造 函数和析构函数的调用顺序。 生出圆类Circle和三角形类Triangle,并求各自的面积。

7.设计一个建筑物基类Buinding,由它派生出宿舍类Hostel和教学楼Classroom,前 者包括楼名、总层数、住户数、总住人数和总面积,后者包括楼名、总层数、教 室数、灭火器数和总面积。

8.派生类构造函数执行的次序是怎样的? 先构造父类,再构造派生类,析构时先析构派生类,再析构父类。 9.比较类的三种继承方式public公有继承、protected保护继承、private私有继承之 间的差别。 公有继承:派生类函数可调用父类公有成员,父类在派生类中公有私有保护性质不变。 保护继承:派生类可调用父类原先的公有和保护成员,父类在派生类中公有和保护成员变为保护成员,私有成员仍为私有。 私有继承:派生类可调用父类原先的公有成员,父类在派生类中公有保护私有全部变成私有,再下一层的派生类无法访问它的任何成员。 10.如果在派生类B已经重载了基类A的一个成员函数fn1(),没有重载成员函数fn2(), 如何调用基类的成员函数fn1()、fn2()? 因为在派生类B已经重载了基类A的一个成员函数fn1(),所以要用作用域运算符对fn1()函数加以限定,调用基类的成员函数fn1()是A::fn1();因为在派生类B没有重载成员函数fn2(),所以直接可调用fn2()。 11.(选做题)设计一个圆类Circle和一个桌子类Table,另设计一个圆桌类RoundTable, 它是从前两个类派生出来的,要求输出一个圆桌的高度、桌面半径、面积和颜色等数据。 提示:利用多继承class RoundTable:public Table,public Circle

C++习题第07章 继承和派生

第07章继承和派生 (1)面向对象程序设计的____机制实现了代码重用,有效地缩短了程序的开发周期。(2)在继承关系中,被继承的类称为____,通过继承关系定义出来的新类称为_____。(3)派生类的继承方式有____ ,____ 和____3种,其中默认的继承方式为____.。 (4)公有继承时,基类的私有成员为跑生类的____成员,基类的保护成员成为派生类的____成员,基类的公有成员成为派生类的____成员。 (5)在派生类中不能访问基类的____成员,这符合面向对象程序设计的封装思想。(6)C++语言不仅支持____继承,也支持____继承。 (7)可以把派生类的对象当做基类对象来处理,这是____的概念。 (8)根据联编实现的不同极端,可将其分为____联编和____联编两种。 (9)声明了纯虚函数的类,称为____。 2.选择题 (1)下列关于派生类的描述中,不正确的是() A)派生类的成员除了包含它自己的成员的访问权限在派生类中保持不变 B)派生类中继承的基类 C)派生类至少有个一个基类 D)一个派生类可以作为另一个派生的基类 (2)在保护继承中,基类的私有成员变成派生类的() A)不可访问成员B)稀有成员C)保护成员D)公有成员 (3)若有如下类声明: Class Base { int k; Public: Void set(int n){k=n;} Int get()const{return k;} }; Class Derived:protected Base {protected: Int j; Public: Void set(int m,int n) { Base::set(m); j=n; } Int get()const { return Base::get()+j; } }; 则类Derived中保护的数据成员和成员函数的个数是() A)4 B)3 C)2 D)1 (4)在派生类的结构函数的初始化表中,不能包含()

C++程序设计练习题及答案第七章继承

第7章继承 7.1 选择题 1.在c++中,类与类之间的继承关系具有( c )。 (a) 自反性 (b) 对称性 (c) 传递性 (d) 反对称性 2.下列关于类的继承描述中,( a,b )是错误的。 (a) 派生类可以访问基类的所有数据成员,调用基类的所有成员函数 (b) 派生类也是基类,所以基类具有派生类的全部属性和方法 (c) 继承描述类的层次关系,派生类可以具有与基类相同的属性和方法 (d) 一个基类可以有多个派生类,一个派生类可以有多个基类 3.当一个派生类公有继承一个基类时,基类中的所有公有成员成为派生类的( a )。 (a) public 成员 (b)private成员 (c) protected成员 (d)友员 4.当一个派生类私有继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( b )。 (a) public 成员 (b)private成员 (c) protected成员 (d)友员 5.当一个派生类保护继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( c )。 (a) public 成员 (b)private成员 (c) protected成员 (d)友员 6.不论派生类以何种方式继承基类,都不能使用基类的( b )。 (a) public 成员 (b)private成员 (c) protected成员 (d)public 成员和protected成员 7.下面描述中,错误的是( b, c )。 (a) 在基类定义的public成员在公有继承的派生类中可见,也能在类外被访问 (b) 在基类定义的public和protected成员在私有继承的派生类中可见,在类外可以被访问 (c) 在基类定义的public和protected成员在保护继承的派生类中不可见 (d) 在派生类中不可见的成员要变成可访问的需进行访问声明 8.在c++中,不能被派生类继承的函数是( b,c )。 (a) 成员函数 (b)构造函数 (c) 析构函数 (d)静态成员函数 9.在创建派生类对象时,构造函数的执行顺序是( d )。 (a) 对象成员构造函数、基类构造函数、派生类本身的构造函数 (b) 派生类本身的构造函数、基类构造函数、对象成员构造函数

相关主题
文本预览
相关文档 最新文档