C++面向对象程序设计第8章 继承与派生习题解答
C++教程第08章 继承与派生-5-7
第8章继承与派生8-1. 教学目的与要求1.理解继承的概念;2.掌握继承的实现方法;3.继承中常见问题的处理方法。
8-2. 主要内容及重点:类是C++中进行数据封装的逻辑单位。
继承是面向对象程序设计的一个重要特征之一,它允许在既有类的基础上创建新的类,新类可以从一个或多个既有类中继承操作和数据,而且可以重新定义或加进新的数据和操作,从而形成类的层次或等级。
既有类称为基类或父类,在它基础上建立的新类称为派生类、导出类或子类。
本章的重点是派生类的定义和使用、创建派生类对象时构造函数的调用顺序、多重继承中的冲突及其消除方法以及作用域运算符的几种使用方法等。
本章的难点是基类的初始化、多重继承中的冲突以及虚基类等。
8-3. 第8章继承-课件3-4. 8-4. 第8章继承-复习总结继承是面向对象程序设计方法的基本特性之一,继承可以提高软件的重要性。
本章主要介绍了C++中的继承性的实现方法以及在继承性常见问题的处理方法。
包括基类的初始化、访问类型的调整、冲突及其消除方法、成员覆盖、赋值兼容性以及虚基类等。
类的派生包括三种类型:私有派生、保护派生、公有派生。
利用构造函数的初始化成员列表,可以在派生类中对基类成员进行初始化。
在继承层次关系中要避免冲突的产生,通常是采用指定作用域和定义虚基类这两种方法来解决问题。
8-5. 第8章继承-练习8-5-1.思考题:1).派生类有几种方式,每种方式中派生类对基类成员的继承如何?2). 在创建派生类对象时,构造函数的执行次序是怎样的?析构函数的执行次序是怎样的?3). 派生类对象如何对基类中的成员进行初始化?4). 在多重继承中,在什么情况下会产生冲突?如何消除冲突? 5). 列举我们已学习的作用域运算符“::”的所有用途。
6). 属于不同类的对象在什么情况下可以互相赋值? 7).什么叫虚基类?为什么要引进虚基类?8-5-2.练习题:课后练习题见练习单元。
第8章 继承与派生继承是面向对象程序设计的一个重要特征之一,它允许在既有类的基础上创建新的类,新类可以从一个或多个既有类中继承操作和数据,而且可以重新定义或加进新的数据和操作,从而形成类的层次或等级。
《C++程序设计》习题解答
《C++程序设计》习题解答第1章C++概述1.填空题(1)在面向对象程序设计中,对象是由___________、___________和___________封装在一起构成的实体。
(2)在面向对象程序设计中,类是具有________________和___________的对象的集合,它是对一类对象的抽象描述。
(3)面向对象程序设计最突出的特点就是___________、___________和___________。
(4)C++语言包含头文件的格式有两种,即_______________和__________________。
(5)C++源程序要经过________、_________、________和_________四个环节,才能在屏幕上显示结果。
(6)每个C++程序都从________函数开始执行。
(7)每个函数体都以________开始,以________结束。
(8)C++程序中的每条语句以________结束。
(9)C++程序的头文件和源程序的扩展名分别为__________和_________,目标程序的扩展名为__________,可执行程序的扩展名为__________。
(10)在C++程序中使用基本输入/输出语句需包含的头文件是________________,应放在程序的________________。
(11)在C++程序中注释语句有_______________和______________两种格式。
(12)C++程序的续行符为_________。
(13)如果从键盘输入语句给变量X,则输入函数的形式为_____________;如果再将变量X的值显示在屏幕上,其输出函数的形式为_____________。
(14)C++程序中的“endl”在输出语句中起___________作用。
参考答案:(1)对象名,一组属性数据,一组操作(2)相同属性数据,操作(3)封装性,继承性,多态性(4)#include<文件名.扩展名>,#include"文件名.扩展名"(5)编辑,编译,连接,运行(6)主函数(7){、}(8)分号;(9).h,.cpp,.obj,.exe(10)#include<iostream.h>,开始部分(11)/* */,//(12)\(13)cin>>X、cout<<X(14)换行并清空流2.选择题(1)面向对象程序设计把数据和()封装在一起。
c面向对象课后答案第8章
在C++中,三种派生方式的说明符号为认的派生方式为private OPublicprivate、p rotected 不加说明,则默当公有派生时,基类的公有成员成为派生类的公有成员;保护成员成为派生类的保护成且;私有成员成为派生类的不能直接访问成员O当保护派生时,基类的公有成员成为派生类的保护成员;保护成员成为派生类的保护成员;私有成员成为派生类的不能直接访问成员O派生类的构造函数一般有3项工作要完成:首先基类初始化,其次成员对彖初始化,最后执行派生类构造函数体O多继承时,多个基类中的同名的成员在派生类中由于标识符不唯一而岀现类中采二义性。
在派生用虚基类或作用域分辨符来消除该问题。
2.简答题派生类如何实现对基类私有成员的访问什么是类型兼容规则派生类的构造函数是怎样的执行顺序,析构函数的执行顺序是如何实现的继承与组合之间的区别与联系是什么什么是虚基类它有什么作用含有虚基类的派生类的构造函数有什么要求,什么是最远派生类,建立一个含有虚基类的派生类的对象时,为什么由最远派生类的构造函数负责虚基类的初始化3•选择题下面对派生类的描述屮,错误的是(一个派生类可以作为另外一个派生栄的基类A.派生类至少有一个基类B.派生类的成员除了它自己的成员外,还包含了它的基类的成员C.派生类屮继承的基类成员的访问权限到派生类屮保持不变D.下列对友元关系叙述正确的是(A) oA.不能继承是类与类的B.关系是一个类的成员函数与另一个类的关系提高程序的运行效率当保护继承时,基类的 C(B)在派生类中成为保护成员,不能通过派生类的对象来直接访问。
A任何成员 B.公有成员和保护成员nC.公有成员和私有成员D.私有成员设置虚基类的目的是(B) oA简化程序B•消除二义性C.提高运行效率D.减少目标代码在公有派生情况下,有关派生类对象和基类对象的关系,不正确的叙述是( C ) OA.派生类的对象可以赋给基类的对象派生类的对象可以初始化基类的引用派生类的对B.象可以直接访问基类中的成员派生类的对象的地址可以赋给指向基类的指针C.D.有如下类定义:class MvBASE{int k; public :void set (int n) {k=n;} int get( ) const {return k;} };class MyDERIVED: protected MyBASE{ protected; int j ; public :void set (int m, int n){MyBASE::set(m);j=n;} int get( ) const{return MyBASE::get( )+j ;} }; 则类MyDERIVE [中保护成员个数是(B)。
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)?答:如果派生类声明了一个和某个基类成员同名的新成员(当然如是成员函数,参数表也必须一样,否则是重载),派生类中的新成员就屏蔽了基类同名成员,类似函数中的局部变量屏蔽全局变量。
C++(练习)第8章,继承与派生
C++(练习)第8章,继承与派生一,单选题1.下列描述中错误的是( )。
A 继承分为多重继承和单继承B 对象间通信靠传递消息实现C 在外面看不到对象的内部特征是基于对象的"模块独立性好"这个特征D 类是具有共同属性、共同方法的对象的集合参考答案C2. 设有以下定义:#includeclass A1{public:void show1() { cout<<"class A1"<<="">};class A2: public A1{public:void show2( ) { cout<<"class A2"<<="">};class A3: protected A2{public:void show3( ) { cout<<"class A3"<<="">};void main(){A1 obj1;A2 obj2;A3 obj3;...}以下不合法的调用语句是( )。
A obj1.show1();B obj2.show1();C obj3.show1();D obj2.show2();参考答案C3. 下列描述中哪个是正确的__________。
A 私有派生的子类无法访问父类的成员B 类A的私有派生子类的派生类C无法初始化其祖先类A对象的属性,因为类A的成员对类C是不可访问的C 私有派生类不能作为基类派生子类D 私有派生类的所有子孙类将无法继续继承该类的成员参考答案B4. 下面有关派生类的说法中,错误的是( )。
A 一个派生类可以作为另一个派生类的基类B 一个派生类可以有多个基类C 派生类构造函数可以将初始化参数值传递给基类的构造函数和对象成员的构造函数D 具有继承关系时,基类成员在派生类中的访问权限不变参考答案D5. 设置虚基类的目的是( )。
程序设计教程(机械工业出版社)课后习题答案 第8章 继承――派生类
第8章继承――派生类1、在C++中,protected类成员访问控制有什么作用?答:C++中引进protected成员保护控制,缓解了数据封装与继承的矛盾。
在基类中声明为protected的成员可以被派生类使用,但不能被基类的实例用户使用,这样能够对修改基类的内部实现所造成的影响范围(只影响子类)进行控制。
protected成员保护控制的引进使得类有两种接口:与实例用户的接口和与派生类用户的接口。
2、在C++中,三种继承方式各有什么作用?答:类的继承方式决定了派生类的对象和派生类的派生类对基类成员的访问限制。
public继承方式使得基类的public成员可以被派生类的对象访问,它可以实现类之间的子类型关系;protected继承使得基类的public成员不能被派生类的对象访问,但可以被派生类的派生类访问;private继承使得基类的public成员既不能被派生类的对象访问,也不能被派生类的派生类访问。
protected和private继承主要用于实现上的继承,即纯粹为了代码复用。
3、在多继承中,什么情况下会出现二义性?怎样消除二义性?答:在多继承中会出现两个问题:名冲突和重复继承。
在多继承中,当多个基类中包含同名的成员时,它们在派生类中就会出现名冲突问题;在多继承中,如果直接基类有公共的基类,就会出现重复继承,这样,公共基类中的数据成员在多继承的派生类中就有多个拷贝。
在C++中,解决名冲突的方法是用基类名受限;解决重复继承问题的手段是采用虚基类。
4、写出下面程序的运行结果:#include <iostream>using namespace std;class A{ int m;public:A() { cout << "in A's default constructor\n"; }A(const A&) { cout << "in A's copy constructor\n"; }~A() { cout << "in A's destructor\n"; }};class B{ int x,y;public:B() { cout << "in B's default constructor\n"; }B(const B&) { cout << "in B's copy constructor\n"; }~B() { cout << "in B's destructor\n"; }};class C: public B{ int z;A a;public:C() { cout << "in C's default constructor\n"; }C(const C&) { cout << "in C's copy constructor\n"; }~C() { cout << "in C's destructor\n"; }};void func1(C x){ cout << "In func1\n";}void func2(C &x){ cout << "In func2\n";}int main(){ cout << "------Section 1------\n";C c;cout << "------Section 2------\n";func1(c);cout << "------Section 3------\n";func2(c);cout << "------Section 4------\n";return 0;}答:------Section 1------in B's default constructorin A's default constructorin C's default constructor------Section 2------in B's default constructorin A's default constructorin C's copy constructorIn func1in C's destructorin A's destructorin B's destructor------Section 3------In func2------Section 4------in C's destructorin A's destructorin B's destructor5、写出下面程序的运行结果:#include <iostream>using namespace std;class A{ int x,y;public:A() { cout << "in A's default constructor\n"; f(); }A(const A&) { cout << "in A's copy constructor\n"; f(); }~A() { cout << "in A's destructor\n"; }virtual void f() { cout << "in A's f\n"; }void g() { cout << "in A's g\n"; }void h() { f(); g(); }};class B: public A{ int z;public:B() { cout << "in B's default constructor\n"; }B(const B&) { cout << "in B's copy constructor\n"; }~B() { cout << "in B's destructor\n"; }void f() { cout << "in B's f\n"; }void g() { cout << "in B's g\n"; }};void func1(A x){ x.f();x.g();x.h();}void func2(A &x){ x.f();x.g();x.h();}int main(){ cout << "------Section 1------\n";A a;A *p=new B;cout << "------Section 2------\n";func1(a);cout << "------Section 3------\n";func1(*p);cout << "------Section 4------\n";func2(a);cout << "------Section 5------\n";func2(*p);cout << "------Section 6------\n";delete p;cout << "------Section 7------\n";return 0;}答:------Section 1------in A's default constructorin A's fin A's default constructorin A's fin B's default constructor------Section 2------in A's copy constructorin A's fin A's fin A's gin A's fin A's gin A's destructor------Section 3------in A's copy constructorin A's fin A's fin A's gin A's fin A's gin A's destructor------Section 4------in A's fin A's gin A's fin A's g------Section 5------in B's fin A's gin B's fin A's g------Section 6------in A's destructor------Section 7------in A's destructor6、利用习题6.8的第14题中的时间类Time,定义一个带时区的时间类ExtTime。
面向对象程序设计C课后题答案
第一章:面向对象程序设计概述[1_1]什么是面向对象程序设计?面向对象程序设计是一种新型的程序设计范型。
这种范型的主要特征是:程序=对象+消息。
面向对象程序的基本元素是对象,面向对象程序的主要结构特点是:第一:程序一般由类的定义和类的使用两部分组成,在主程序中定义各对象并规定它们之间传递消息的规律。
第二:程序中的一切操作都是通过向对象发送消息来实现的,对象接受到消息后,启动有关方法完成相应的操作。
面向对象程序设计方法模拟人类习惯的解题方法,代表了计算机程序设计新颖的思维方式。
这种方法的提出是软件开发方法的一场革命,是目前解决软件开发面临困难的最有希望、最有前途的方法之一。
[1_2]什么是类?什么是对象?对象与类的关系是什么?在面向对象程序设计中,对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。
对象可以认为是:数据+操作在面向对象程序设计中,类就是具有相同的数据和相同的操作的一组对象的集合,也就是说,类是对具有相同数据结构和相同操作的一类对象的描述。
类和对象之间的关系是抽象和具体的关系。
类是多个对象进行综合抽象的结果,一个对象是类的一个实例。
在面向对象程序设计中,总是先声明类,再由类生成对象。
类是建立对象的“摸板”,按照这个摸板所建立的一个个具体的对象,就是类的实际例子,通常称为实例。
[1_3]现实世界中的对象有哪些特征?请举例说明。
对象是现实世界中的一个实体,其具有以下一些特征:(1)每一个对象必须有一个名字以区别于其他对象。
(2)需要用属性来描述它的某些特性。
(3)有一组操作,每一个操作决定了对象的一种行为。
(4)对象的操作可以分为两类:一类是自身所承受的操作,一类是施加于其他对象的操作。
例如:雇员刘名是一个对象对象名:刘名对象的属性:年龄:36 生日:1966.10.1 工资:2000 部门:人事部对象的操作:吃饭开车[1_4]什么是消息?消息具有什么性质?在面向对象程序设计中,一个对象向另一个对象发出的请求被称为“消息”。
C++面向对象程序设计习题 继承与派生
继承与派生练习题1.什么是继承性?为什么说它是面向对象程序中的重要机制?2.C++中继承分为哪两个类?继承方式又分哪三种?3.三中继承方式中有哪些特点?不同基础更方式中派生类的对象对基类成员的访问有何不同?4.如何定义单继承的派生类?如何定义多继承的派生类?5.派生类与基类之间有什么关系?6.单继承中,派生类的构造函数定义格式如何?7.多继承中,派生类的构造函数定义格式如何?8.多继承中,在哪些情况下会出现二义性?如何消除二义性?9.为什么要引入虚基类?带有虚基类的派生类的构造函数有什么特点?作业题一、选择填空1.下列对派生类的描述中,(D )是错的。
A.一个派生类可以作另一个派生类的基类;B.派生类至少有一个基类;C.派生类的成员除了它自己的成员外,还包含了它的基类的成员;D.派生类中继承的基类成员的访问权限到派生类保持不变。
2.派生类的对象对它的基类成员中(A )是可以访问的。
A.公有继承的公有成员;B.公有继承的私有成员;C.公有继承的保护成员;D.私有继承的公有成员。
3.派生类的构造函数的成员初始化列表中,不能包含(D )。
A.基类的构造函数;B.派生类中对象成员的初始化;C.基类的对象成员的初始化;D.派生类中一般数据成员的初始化。
4.关于多继承二义性的描述中,(C)是错的。
A.一个派生类的两个基类中都有某个同名成员,在派生类中对这个成员的访问可能出现二义性;B.解决二义性的最常用的方法是对成员名的限定义;C.基类和派生类中同时出现的同名函数,也存在二义性问题;(调用时才会出现二义性)D.一个派生类是从两个基类派生出来的,而这两个基类又有一个共同的基类,对该基类成员进行访问时,也可能出现二义性。
7.设置虚基类的目的是(B )A.简化程序;B.消除二义性;C.提高运行效率;D.减少目标代码。
8.带有虚基类的多层派生类构造函数的成员初始化列表中虚基类的构造函数将被初始化(D)A.类下面的派生类个数有关;B.二次;C.二次;D.一次。
c 继承与派生习题答案
继承与派生概念填空题1.1在C++中,三种派生方式的说明符号为public、private、protected不加说明,则默认的派生方式为private。
1.2当公有派生时,基类的公有成员成为派生类的公有成员;保护成员成为派生类的保护成员;私有成员成为派生类的不能直接访问成员。
当保护派生时,基类的公有成员成为派生类的保护成员;保护成员成为派生类的保护成员;私有成员成为派生类的不能直接访问成员。
1.3 派生类的构造函数一般有3项工作要完成:首先基类初始化,其次成员对象初始化,最后执行派生类构造函数体。
1.4多继承时,多个基类中的同名的成员在派生类中由于标识符不唯一而出现二义性。
在派生类中采用虚基类或作用域分辨符来消除该问题。
3.选择题3.1下面对派生类的描述中,错误的是(D )。
A.一个派生类可以作为另外一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类的成员D.派生类中继承的基类成员的访问权限到派生类中保持不变3.2下列对友元关系叙述正确的是(A)。
A.不能继承B.是类与类的关系C.是一个类的成员函数与另一个类的关系D.提高程序的运行效率3.3当保护继承时,基类的(B)在派生类中成为保护成员,不能通过派生类的对象来直接访问。
A.任何成员B.公有成员和保护成员C.公有成员和私有成员D.私有成员3.4设置虚基类的目的是(B)。
A.简化程序B.消除二义性C.提高运行效率D.减少目标代码3.5在公有派生情况下,有关派生类对象和基类对象的关系,不正确的叙述是(C )。
A.派生类的对象可以赋给基类的对象B.派生类的对象可以初始化基类的引用C.派生类的对象可以直接访问基类中的成员D.派生类的对象的地址可以赋给指向基类的指针3.6有如下类定义:class MyBASE{int k;public:void set(int n) {k=n;}int get( ) const {return k;}};class MyDERIVED: protected MyBASE{protected;int j;public:void set(int m,int n){MyBASE::set(m);j=n;}int get( ) const{return MyBASE::get( )+j;}};则类MyDERIVED中保护成员个数是(B)。
继承与派生类答案
继承与派生类知识要点1.掌握继承和派生的定义,派生类的定义方法。
(1)掌握继承的两种类型:单继承和多继承。
(2)掌握private,public,protected三种继承方式的特点。
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:基类的private成员在派生类中不可见。
区别:对于私有继承,基类的public、protected成员在派生类中作为private成员;对于公有继承,基类的public、protected成员在派生类中访问属性不变;对于保护继承,基类的public、protected成员在派生类中作为protected成员。
(3)掌握派生类中的构造函数和析构函数的使用。
基类的构造函数和析构函数不能继承,所以必要时在派生类中定义自己的构造函数和析构函数。
派生列的构造函数完成基类中新增数据成员和基类数据成员的初始化,基类数据成员的初始化通过基类构造函数来实现。
(4)掌握派生类的同名覆盖规则。
(5)掌握赋值兼容规则。
基类对象可以使用公有派生类对象来代替,包括:派生类对象可以赋值给基类对象;派生类对象可以初始化基类对象的引用;基类类型指针可以指向派生类对象。
2.掌握多重继承的概念、定义方法、多重继承派生类构造函数的执行顺序。
派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类时指定的各基类顺序),在执行对象成员所在类的构造函数(顺序按照他们在类中的声明顺序),最后执行派生类构造函数体中的内容。
3.掌握虚基类的概念和定义方法。
在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
典型例题分析与解答例题1:下列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变答案:D分析:一个派生类可以作为另一个派生类的基类。
C++面向对象程序设计第八章继承与派生
13
8.4
派生类的构造函数与析构函数
在产生新的对象时, 都会调用相应的构造函数。 构造函数的作用有两点: (1)为成员变量分配存储空间。 (2)初始化成员变量的值。 派生类的构造函数? 析构函数? 基类的构造函数和析构函数是不能被继承的!
14
8.4.1简单派生类的构造函数
25
8.7继承与组合
在实际的程序开发过程中,使用面向对象的方 法,在建立新类的时候,要弄清新类与已有类 之间的关系 看究竟是 看究竟是ISA关系还是HASA关系? 关系还是 关系? 如果是ISA关系,就要通过继承来产生新的类 如果是HASA关系,就要通过组合来产生新的类
【例8.14】继承与组合示例 】
21
8.5.3多重继承的问题 【例8.10】 多重继承的问题 】
解决的办法之一:在处理变量时通过 基类名加上域作用符的方式 指明要操作的究竟是哪个变量 这样即不符合现实,还浪费了存储空间 解决的办法之二: 采用 虚基类
22
8.5.4虚基类
在继承时通过关键字virtual声明为虚继承, 相应的基类就成了虚基类。
6
8.2
派生类的声明方式及构成
比较这个定义和上一节中给出的undergraduate 定义,很容易发现继承的写法: 默认为private私 默认为 私
有继承 基类名1, 基类名2, class 子类名 : 继承方式 基类名 ,继承方式 基类名 , [继承方式] 父类名 …继承方式 基类名 继承方式 基类名n { 继承方式可以是 public(公有继承) (公有继承) 类的定义体 private(私有继承) (私有继承) protected(保护继承) (保护继承) };
C 面向对象程序设计习题解答(全)
4答案 n=2,sum=2 n=3,sum=5 n=5,sum=10
5答案 x=3 6答案 x=1,y=2 x=30,y=40 7答案 1 2 3 4 exit main 3 2 1 8答案 n=100 9答案 the student is:Li Hu the teacher is:Wang Ping 10答案 2 11答案 1035,789.504 12答案 13答案
一、选择题 1 2 3 4 D B B C
类和对象的进一步解析
5 D 6 D 7 D B 8 C B 9 10 11 12 13 14 15 16 B D B A A C B A
17 18 19 20 21 22 23 24 C C D B A D 二、填空题 1 this 2所有成员 3友元类、友元函数 4 friend 5 程序编译、程序结束 三、程序阅读题
第六章 派生与继承
一、选择题 1(1) 1(2) 2 A B 3 4 5 6 7 8 9 10 11 D C C C D D B C A D
二、填空题 1 继承 2 具体化、抽象 3 公有继承、保护继承、私有继承 4 子对象 5 public(共有的)、protected(保护的)、不可访问 6 protected(保护的)、protected(保护的)、不可访问的 7 private(私有的)、private(私有的)、不可访问的 8 二义性 三、判断下列描述的正确性 1 2 3 4 5 6 7 8 9 10 11 12 13 √ × × × × × √ √ × × √ √ ×
1、 选择题 1 2 3 4 5 6 7 C 8 9 10 D D D C A D C 2、 程序阅读题 1答案 a=639,b=78,c=12 2答案 a=5,b=8 a=8,b=5 3答案 10 4答案 x=20.6 y=5 z=A x=216.34 y=5 z=A x=216.34 y=2 z=A x=216.34 y=2 z=E 5答案 ic=11 fc=7.82 ic=5 fc=2.15 3、 判断下列描述的正确性 1 2 √ × D A
C++继承和派生编程参考答案
继承和派生练习一1.以日期类cDate(有数据成员年月日)为基类派生日期时间类cTime,新增数据成员时分秒,要求有构造函数、输出所有成员的函数,测试程序正确性。
#include<iostream.h>class cDay{int ye,mo,da;public:cDay(int a=2000,int b=1,int c=1){ye=a,mo=b,da=c;}void Dout(void){cout<<ye<<' '<<mo<<' '<<da<<endl;}};class cTime:public cDay{int ho,mi,se;public:cTime(int a=2000,int b=1,int c=1,int d=12,int e=12,int f=12):cDay(a,b,c){ho=d,mi=e,se=f;}void Tout(void){Dout();cout<<ho<<' '<<mi<<' '<<se<<endl;}};void main(void){cTime t1(2010,4,30,15,20,23);t1.Tout();}2.以三维坐标类cPoint为基类派生圆类cCircle,新增数据成员半径;再以圆类为基类派生圆柱体类cColumn,新增数据成员高度,要求有构造函数、输出所有成员的函数,在相关类中定义求圆面积的成员函数、求体积的成员函数,测试程序正确性。
#include<iostream.h>#define PI 3.1415926class cPoint{float x,y,z;public:cPoint(float a=1,float b=1,float c=1){x=a,y=b,z=c;}void Pout(void){cout<<"x="<<x<<" y="<<y<<" z="<<z;}};class cCircle:public cPoint{float r;public:cCircle(float a=1,float b=1,float c=1,float d=2):cPoint(a,b,c){r=d;}float area(void){return PI*r*r;}void Cout(void){Pout();cout<<" r="<<r;}};class cColumn:public cCircle{float h;public:cColumn(float a=1,float b=1,float c=1,float d=2,float e=3):cCircle(a,b,c,d){ h=e;}float v(void){return area()*h;}void Coout(void){Cout();cout<<" h="<<h<<endl;}};void main(void){cCircle t1(1,2,3,4);t1.Cout();cout<<" area="<<t1.area()<<endl;cColumn t2(2,3,4,5,6);t2.Coout();cout<<"v="<<t2.v()<<endl;}。
最新《c 程序设计基础》第八章-继承和派生
❖ 方法二:面向对象?
▪ class circle 圆形
泛 ▪ class rectangle 矩形 化 ▪ class triangle 三角形 ? ▪ 基类: class shape
shape
• 色彩 color • 位置 (x, y)
circle rectangle
triangle
10
8.2.1 简单的继承和派生
class Shape: { public:
Shape(int x=0, int y=0, char c = 'R'); int GetX() const; void SetX( int x); int GetY() const; void SetY( int x); char GetColor() const; void SetColor(char c); protected: char m_color; int m_x; int m_y; };
17
class base {…… }; class deriver1:public base { …… }; class deriver2:public deriver1 {…… }
8.2.2 定义派生类
• 父类被称为子类的直 接基类
• 父类的父类或更高层 次的父类被称为这个 子类的间接基类
18
例2-图形类及其派生类的声明
的访问权限。 ❖ 每一个“继承方式”,只用于限制对紧随其后之基类的继承。
class derive : public b1 , private b2 { private:
int newInt; public:
void newFun(); private:
int max( int a, int b ); };
最新《C++程序设计案例教程》习题答案第8章 类的继承与派生
第8章类的继承与派生一、选择题1.D 2.A 3.A 4.B 5.B 6.B二、程序题(略)三、简答题1.派生类对基类的继承方式有哪些?在派生类中,成员有几种不同的访问属性?答:派生类对基类的继承方式有三种:public、protected、private。
成员也有三种访问属性:public、protected、private。
2.多级派生的访问属性如何确定?答:多级派生的访问属性确定的原则与单层派生一致。
3. 在执行派生类时,如何调用基类的构造函数?答:在派生类构造函数的初始化列表中描述。
4. 对数据成员初始化时,如何对子对象初始化?答:在派生类构造函数的初始化列表中,写上子对象名(实际参数)。
5.程序中有多重继承时,系统如何调用析构函数?答:按照调用构造函数相反的顺序调用析构函数。
6.举例说明多重继承引起的二义性,如何解决此问题?多重继承指一个类从多个基类中派生而来。
如果一个派生类有多个直接基类,而这些直接基类又都派生于同一个基类,则在最终派生类中会保留间接基类中的多份数据成员,从而导致在派生类中访问这些数据成员时,可能产生错误,即二义性的错误。
C++提供了虚基类(virtual base class)的方法来解决这个问题,使得派生类在获得间接基类的数据成员时只保留一份拷贝。
7. 谈谈虚基类的作用。
在进行多重继承时,为保证最终派生类中只继承一次,通常声明该基类为所有直接派生类的虚基类。
如果虚基类中定义了带参数的构造函数,则在其所有的派生类(直接派生类或者间接派生类)中,必须通过这些派生类的构造函数对虚基类构造函数调用。
但是,其实只有最后的派生类成功地调用了虚基类的构造函数,并对虚基类的数据成员进行了初始化,其余派生类中对虚基类的调用只是形式,以形成派生类构造函数声明格式的一致性,而没有真正调用虚基类的构造函数。
这就保证了虚基类的数据成员不会被多次初始化。
四、编程题分别声明Teacher类和Cadre类,采用多重继承方式由这两个类派生出新类TC类。
c 继承与派生练习题
c 继承与派生练习题C++是一种面向对象的编程语言,其中最重要的概念之一就是继承与派生。
继承允许一个类(称为派生类)从另一个类(称为基类)中继承属性和行为。
这个过程允许我们在派生类中使用基类的成员,同时还可以添加新的成员或者修改基类成员的行为。
在这篇文章中,我们将通过一些练习题来巩固与继承与派生有关的概念和技能。
这些练习题旨在帮助读者更好地理解和应用这些概念。
首先,考虑一下以下的代码段:```cppclass Shape {protected:int width, height;public:Shape(int w, int h) : width(w), height(h) {}virtual int area() = 0;};class Rectangle : public Shape {public:Rectangle(int w, int h) : Shape(w, h) {}int area() override { return width * height; }};class Triangle : public Shape {public:Triangle(int w, int h) : Shape(w, h) {}int area() override { return (width * height) / 2; }};```通过观察上述代码,我们可以看到Shape是一个基类,其派生类有Rectangle和Triangle。
这些派生类通过公有继承的方式继承了Shape类的成员。
另外,注意到Shape类中的区域函数area()被声明为纯虚函数。
接下来,我们通过一些练习题来检验对继承和派生的理解。
练习题1:向Shape的派生类中添加新的成员在给定的代码段中,尝试向Rectangle和Triangle类中添加一个新的成员,例如颜色color。
然后,尝试在main()函数中创建一个Rectangle对象和一个Triangle对象,并打印出它们的属性(包括颜色)和区域。
继承和派生习题与解析
vehicle类是基类由它派生出car类和truck类将公共 的属性和方法放在vehicle类中。 本题程序如下:
#include<iostream.h> class vehicle // 定义汽车类 {
protected: int wheels; // 车轮数 float weight; // 重量
解: 本题说明 派生类中含有对象成员情况下构造函数和析构函数
的调用顺序。这里base为基类,subs为派生类,subs类的构造 函数中含有对象成员。 所以输出为:
constrcuting base class n=1 constructing base class n=3 constructing sub class m=2 destructing sub class destructing base class destructing base class 注意:当派生类中含有对象成员时,构造函数的调用顺序如下: 1)基类的构造函数 2)对象成员的构造函数 3)派生类的构造函数
class subs:public base {
base bobj; int m; public:
subs(int a,int b,int c):base(a),bobj(c) {
cout<<"constructing sub cass"<<endl; m=b; cout<<"m="<<m<<endl; } ~subs(){cout<<"destructing sub class"<<endl;} }; void main() { subs s(1,2,3); }
C++面向对象程序设计第8章 继承与派生
蚌埠学院计算机系
C++面向对象程序设计
class Studend1 可以看出,很多是重复的地方, 我们可以通过C++语言中的 { int num; //此行原来己有 继承机制,可以扩充和完善旧 char name[20]; //此行原来己有 的程序设计以适应新的需求。 char sex; //此行原来己有 这样不仅可以节省程序开发的 时间和资源,并且为未来程序 int age; 增添了新的资源。 char addr[20]; public: void display( ) ; //此行原来己有 {cout<<"num: "<<num<<endl; //此行原来己有 cout<<"name: "<<name<<endl;//此行原来己有 cout<<"sex: "<<sex<<endl; //此行原来己有 cout<<"age: "<<age<<endl; cout<<"address: "<<addr<<endl;} };
蚌埠学院计算机系
21
C++面向对象程序设计
【例8-3】定义类Point,然后定义类Point的派生类 Circle。 #include <iostream.h> class Point //定义基类,表示点 { private: int x; int y; public: void setPoint(int a, int b){ x=a; y=b; }; //设置坐标 int getX(){ return x; }; //取得X坐标 int getY(){ return y; }; //取得Y坐标 };
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第8章习题
一、概念题
1.解答要点如下。
⑴采用public公有派生,基类成员的访问权限在派生类中保持不变,即基类所有的公有或保护成员在派生类中仍为公有或保护成员。
public派生最常用,可以在派生类的成员函数中访问基类的非私有成员,可通过派生类的对象直接访问基类的公有成员。
⑵采用private私有派生,基类所有的公有和保护成员在派生类中都成为私有成员,只允许在派生类的成员函数中访问基类的非私有成员。
private派生很少使用。
⑶采用protected保护派生,基类所有的公有和保护成员在派生类中都成为保护成员,只允许在派生类的成员函数和该派生类的派生类的成员函数中访问基类的非私有成员。
2.解答要点如下。
派生类构造函数的执行次序:首先,调用基类构造函数,调用顺序按照它们被继承时声明的基类名顺序执行;其次,调用内嵌对象构造函数,调用次序为各个对象在派生类内声明的顺序;最后,执行派生类构造函数体中的内容。
派生类析构函数执行过程与构造函数执行过程相反。
即当派生类对象的生存期结束时,首先调用派生类的析构函数,然后调用内嵌对象的析构函数,再调用基类的析构函数。
3.解答要点如下。
在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
引进虚基类的目的是为了解决二义性问题,使得公共基类在它的派生类对象中只产生一个基类子对象。
二、填空题
1.派生类基类
2.public、protected、private
3.virtual
4.基类派生类自身
5.成员函数
三、编程题
1.
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
class base //定义一个基类
{protected:
char name[20]; //姓名
char sex[3]; //性别
int age; //年龄
…
};
class teacher:public base //基类派生出教师类
{ int sno; //工号
char zc[20]; //职称
double wages; //工资
…
};
class student :public base //基类派生出学生类{ int sno; //学号
char bj[10]; //班级
char zy[10]; //专业
double score; //入学成绩…
};
2.
class Shape{
public:
virtual float area()=0;
};
float total(Shape *s[],int n)
{
float sum=0.0;
for(int i=0;i<n;i++)
sum+=s[i]->area();
return sum;
}
class Triangle:public Shape
{
public:
Triangle(double h,double w){H=h;W=w;}
double area() const{return H*W*0.5;}
private:
double H,W;
};
class Rectangle:public Shape
{
public:
Rectangle(double h,double w){H=h;W=w;}
double area()const{return H*W;}
private:
double H,W;
};
3.
#include<iostream.h>
class Vehicle
{
protected:
int wheels;
double weight;
public:
void initialize(int whls, double wght);
int get_wheels() { return wheels; }
double get_weight() { return weight; }
double wheel_loading() { return weight/wheels; }
};
class Car:public Vehicle
{
private:
int passenger_load;
public:
void initialize(int whls, double wght, int people =4);
int passengers() { return passenger_load; }
};
class Truck: public Vehicle
{
private:
int passenger_load;
double payload;
public:
void init_truck(int number =2, double max_load =24000.0);
double efficiency();
int passengers() { return passenger_load; }
};
void Vehicle::initialize(int whls, double wght)
{
wheels=whls;
weight=wght;
}
void Car::initialize(int whls, double wght, int people)
{
wheels=whls;
weight=wght;
passenger_load=people;
}
void Truck::init_truck(int number, double max_load)
{
passenger_load=number;
payload=max_load;
}
double Truck::efficiency()
{
return payload/(payload+weight);
}
void main()
{
Vehicle bicycle;
bicycle.initialize(2,25);
cout<<"the bicycle has "<<bicycle.get_wheels()<<" wheels.\n";
cout<<"the bicycle weighs "<<bicycle.get_weight()<<" pounds.\n";
cout<<"the bicycle's wheel loading is "<<bicycle.wheel_loading()<<" pounds per tire.\n\n";
Car audi;
audi.initialize(4,3500.0,5);
cout<<"the audi has "<<audi.get_wheels()<<" wheels.\n";
cout<<"the audi weighs "<<audi.get_weight()<<" pounds.\n";
cout<<"the audi's wheel loading is "<<audi.wheel_loading()<<" pounds per tire.\n\n";
Truck jief;
jief.initialize(18,12500.0);
jief.init_truck(2,33675.0);
cout<<"the jief has "<<jief.get_wheels()<<" wheels.\n";
cout<<"the jief weighs "<<jief.get_weight()<<" pounds.\n";
cout<<"the jief's efficiency is "<<100.0*jief.efficiency()<<" percent.\n";
}。