实验九 派生与继承—构造与析构参考答案

合集下载

继承与派生例题分析

继承与派生例题分析

虚基类
#include<iostream.h> class A1 { public: A1(){cout<<"A1\ A1(){cout<<"A1\n";} }; class A2 { public: A2(){cout<<"A2\ A2(){cout<<"A2\n";} }; class B1:public A2,virtual public A1 { public: B1(){cout<<"B1\ B1(){cout<<"B1\n";} };
运行结果
The table properties are: Height=15 Area=12.5664 Color=1
多类继承中构造函数和析构函数的执 行顺序
定义一个圆桌类,该类具有桌子类和圆类的特性。 #include <iostream.h> enum Color {Red,Yellow,Green,White}; //圆类Circle的定义 //圆类Circle的定义 class Circle { float radius; public: Circle(float r){radius=r;cout<<“Circle initialized!"<<endl;} initialized! ~Circle(){cout<<"Circle destroyed!"<<endl;} float Area(){return 3.1416*radius*radius;} };
在程序的main函数中,创建派生类的对象bb, 在程序的main函数中,创建派生类的对象bb, 并初始化为(1 并初始化为(1,5,2)。 这时系统

C++第5章习题参考答案

C++第5章习题参考答案

1.什么是类的继承与派生?继承性是面向对象程序设计的第二个重要特性,通过继承实现了数据抽象基础上的代码重用。

继承是对许多问题中分层特性的一种自然描述,因而也是类的具体化和被重新利用的一种手段,它所表达的就是一种对象类之间的相交关系。

它使得某类对象可以继承另外一类对象的特征和能力。

继承所具有的作用有两个方面:一方面可以减少代码冗余;另一方面可以通过协调性来减少相互之间的接口和界面。

通过继承方式定义的子类也称为派生类。

2.类的三种继承方式之间的区别是什么?类的继承方式有public(公有)继承、protected(保护)继承和private(私有)继承三种。

对于不同的继承方式,会导致基类成员原来的访问属性在派生类中有所变化。

表5.1列出了不同继承方式下基类成员访问属性的变化情况。

表5.1 不同继承方式下基类成员的访问属性说明:该表第1列给出3种继承方式,第1行给出基类成员的3种访问属性。

其余单元格内容为基类成员在派生类中的访问属性。

从表中可以看出:(1) 基类的私有成员在派生类中均是不可访问的,它只能由基类的成员访问。

(2) 在公有继承方式下,基类中的公有成员和保护成员在派生类中的访问属性不变。

(3) 在保护继承方式下,基类中的公有成员和保护成员在派生类中均为保护的。

(4) 在私有继承方式下,基类中的公有成员和保护成员在派生类中均为私有的。

需要注意的是:保护成员与私有成员唯一的不同是当发生派生后,处在基类protected区的成员可被派生类直接访问,而私有成员在派生类中是不可访问的。

在同一类中私有成员和保护成员的用法完全一样。

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

具体实现方式:(1) 在类定义体中增加保护段为了便于派生类的访问,可以将基类私有成员中需提供给派生类访问的部分定义为保护段成员。

保护段成员可以被它的派生类访问,但是对于外界是隐藏起来的。

这样,既方便了派生类的访问,又禁止外界对它的派生类访问。

实验9 类的继承和派生

实验9 类的继承和派生

实验9 类的继承和派生一、实验目的1、理解继承的含义,掌握派生类的定义方法和实现;2、理解公有继承下基类成员对派生类成员和派生类对象的可见性,能正确地访问继承层次中的各种类成员;3、理解保护成员在继承中的作用,能够在适当的时候选择使用保护成员以便派生类成员可以访问基类的部分非公开的成员;4、条件编译的运用。

多文件结构的进一步使用。

二、实验内容1、编写一个程序计算出球、圆柱和圆锥的表面积和体积。

要求:(1)定义一个基类,至少含有一个数据成员半径,并设为保护成员;(2)定义基类的派生类球、圆柱、圆锥,都含有求表面积和体积的成员函数和输出函数;(3)编写主函数,求球、圆柱、圆锥的表面积和体积。

2、编写一个学生和教师数据输入和显示程序。

其中,学生数据有编号、姓名、班级和成绩,教师数据有编号、姓名、职称和部门。

要求:(1)将编号、姓名输入和显示设计成一个类person;(2)设计类person的派生类:学生类student和教师类teacher;(3)各个类的声明放在相应的头文件中(*.h),类的实现放在相应的实现文件中(*.cpp):person.h,person.cpp,student.h,student.cpp,teacher.h,teacher.cpp;(4)编写一个主文件(SY4_2.cpp),在该文件中分别定义student、teacher的对象,完成相应功能。

三、实验程序及结果1.#include <iostream>#include <math.h>using namespace std;const double pi=3.1415926;class circle //基类圆{public:circle(double rad){r=rad;}protected:double r;};class ball:public circle //球类{ball(double rad):circle(rad){}void com_surface(){surface=4*pi*r*r;}void com_volume(){volume=4*pi*r*r*r/3;}double get_surface(){return surface;}double get_volume(){return volume;}private:double surface;double volume;};class taper:public circle // 圆锥类{public:taper(double rad,double length):circle(rad){l=length;}void com_surface(){surface=pi*l*r+pi*r*r;}void com_volume(){volume=pi*r*r*sqrt(l*l-r*r)/3;} double get_surface(){return surface;}double get_volume(){return volume;}private:double l; //圆锥侧长double surface;double volume;};class column:public circle //圆柱类{public:column(double rad,double high):circle(rad){h=high;}void com_surface(){surface=pi*r*r*2+2*pi*r*h;} void com_volume(){volume=pi*r*r*h;}double get_surface(){return surface;}double get_volume(){return volume;}private:double h; //圆柱高double surface;double volume;};void main(){_surface();_volume();cout<<"该球的表面积是:"<<b.get_surface()<<endl; cout<<"该球的体积是:"<<b.get_volume()<<endl; cout<<"------------------------------------"<<endl; taper t(3,5);_surface();_volume();cout<<"该圆锥的表面积是:"<<t.get_surface()<<endl; cout<<"该圆锥的体积是:"<<t.get_volume()<<endl; cout<<"------------------------------------"<<endl; column c(3,5);_surface();_volume();cout<<"该圆柱的表面积是:"<<c.get_surface()<<endl; cout<<"该圆柱的体积是:"<<c.get_volume()<<endl; }2、//person.h#include <iostream.h>#include <iomanip.h>const int l=80;class person{ public:void input(){ cout<<"\n input name: ";cin>>name;cout<<"\n certificate no: ";cin>>id;}void print(){ cout<<"\n certificate no: "<<id; }void printname(){ cout<<setw(8)<<name; }private:char name[l],id[l];};//person.cpp#include <iostream.h>#include <iomanip.h>#include<person.h>int main(){person p1;p1.input();p1.print();p1.printname();return 0;}//teacher.h#include <iostream.h>#include <iomanip.h>#include<person.h>class teacher:public person{ public:void input(){ person::input();cout<<" input degree: ";cin>>degree;cout<<" input department: ";cin>>dep;}void print(){ person::print();cout<<"\n degree: "<<"\t"<<degree;cout<<"\n department: "<<"\t"<<dep;}void printname(){ person::printname(); }char degree[l],dep[l];};//teacher.cpp#include <iostream.h>#include <iomanip.h>#include<person.h>#include<teacher.h>int main(){teacher t1;t1.input();t1.print();t1.printname();return 0;}//student.h#include <iostream.h>#include <iomanip.h>#include<person.h>class stud{ public:void input(){ cout<<" input address: ";cin>>addr;cout<<" input telphone no: ";cin>>tel;}void print(){ cout<<"\n address: "<<"\t"<<addr;cout<<"\n telphone no: "<<"\t"<<tel;}private:char addr[l];char tel[l];};class student:private person{ public:void input(){ person::input();cout<<" input years old: ";cin>>old;cout<<" input score no: ";cin>>sno;void print(){ person::print();cout<<"\n tears old: "<<"\t"<<old;cout<<"\n score no: "<<"\t"<<sno;}void printname(){ person::printname(); }private:int old;unsigned long sno;};class score:private student,private stud{ public:void input(){ student::input();stud::input();cout<<"input math score: ";cin>>math;cout<<"input english score: ";cin>>eng;}void print(){ student::print();stud::print();cout<<"\n math score: "<<"\t"<<math;cout<<"\n english svore: "<<"\t"<<eng;cout<<"\n average score: "<<"\t"<<float(math+eng)/2;}void printname(){ student::printname(); }private:int math;int eng;};//student.cpp#include <iostream.h>#include <iomanip.h>#include<person.h>#include<student.h>int main(){stud s1;s1.input();s1.print();student st1;st1.input();st1.print();st1.printname();score sc1;sc1.input();sc1.print();sc1.printname();return 0;}//SY4-2.cpp#include <iostream.h>#include <iomanip.h>#include<person.h>#include<teacher.h>#include<student.h>void main(){ score c1;teacher t1;cout<<"input data for score 1: ";c1.input();cout<<"input data for teacher 1: ";t1.input();cout<<"\n data on student ";c1.printname();c1.print();cout<<"\n data on teacher ";t1.printname();t1.print();}。

实验九答案

实验九答案

第一题:将例11.2的程序片断补充和改写成一个完整、正确的程序,用私有继承方式。

在程序中应包括输入数据的函数,在程序运行时输入num, name, sex, age, addr的值,程序应输出以上5个数据的值。

#include <iostream>#include <string>using namespace std;class Student{public:void get_value(){cout<<"请依次输入学号,姓名,性别"<<endl;cin>>num>>name>>sex;}void display(){cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl;}private:int num;string name;char sex;};class Student1:Student{public:void display_1(){cout<<"age:"<<age<<endl;cout<<"address:"<<addr<<endl;}void set();void show();private:int age;string addr;};void Student1::set(){get_value();cout<<"请依次输入年龄,地址"<<endl;cin>>age;cin>>addr;}void ::Student1::show(){display();cout<<"age:"<<age<<endl;cout<<"addr:"<<addr<<endl;}int main(){Student1 a;a.set();a.show();return 0;}第二题:编写一个程序计算出圆和圆柱体的表面积和体积。

C++(练习)第8章,继承与派生

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. 设置虚基类的目的是( )。

C++面向对象程序设计习题继承与派生

C++面向对象程序设计习题继承与派生

C++面向对象程序设计习题继承与派生继承与派生练习题1.什么是继承性?为什么说它是面向对象程序中的重要机制?所谓继承,就是从先辈处得到属性和行为特征。

2.C++中继承分为哪两个类?继承方式又分哪三种?基类和派生类public(公有)、private(私有)和protected(保护)继承3.三中继承方式中有哪些特点?不同基础更方式中派生类的对象对基类成员的访问有何不同?(1) 公有继承(public)方式:基类中的公有成员和保护成员在派生类中仍然是公有成员和保护成员,而基类的私有成员在派生类中不可访问。

(2) 保护继承(protected)方式:基类中的公有成员和保护成员在派生类中都变成保护成员,而基类的私有成员在派生类中不可访问。

(3) 私有继承(private)方式:基类中的公有成员和保护成员在派生类中都变成私有成员,而基类的私有成员在派生类中不可访问。

因此,无论哪种继承方式,基类中的私有成员在派生类中都不允许访问,基类中的公有成员和保护成员都可以被派生类中的成员直接访问。

派生类对象对基类成员的访问1. 保护继承在类定义中,在关键字protected下说明的成员称为保护成员。

保护成员既具有私有的特性又具有公有的特性。

2. 公有继承在公有继承方式下,基类中的公有成员和保护成员在派生类中仍然是公有成员和保护成员,因此,派生类的其它成员可以直接访问它们,但通过派生类的对象只能访问基类的公有成员,不能访问基类的保护成员和私有成员。

3. 私有继承在私有继承方式下,基类中的公有成员和保护成员在派生类中都变成私有成员,因此,派生类的其它成员可以直接访问它们,但通过派生类的对象不能访问基类的任何成员。

4.如何定义单继承的派生类?如何定义多继承的派生类?一个派生类只有一个直接基类,则该继承称为单一继承一个派生类有多个直接基类,则该继承称为多重继承5.派生类与基类之间有什么关系?在面向对象程序设计中,继承就是一个新类可以从现有类获得特征,从现有类产生新类的过程就是类的派生。

C++实验三继承和派生类(附答案)

实验三继承和派生类实验目的和要求1.理解类的继承的概念,能够定义和使用类的继承关系。

2.掌握派生类的声明与定义方法。

3.熟悉公有派生和私有派生的访问特性。

4.学习虚基类在解决二义性问题中的作用。

实验内容1.先阅读下面的程序,分析程序运行的结果,然后再上机运行程序,验证自己分析的结果是否正确。

(1)#include<iostream.h>class A{public:A(){cout<<"A::A() called.\n";}~A(){cout<<"A::~A() called.\n";}};class B:public A{public:B(int i){cout<<"B::B() called.\n";buf=new char[i];}~B(){delete []buf;cout<<"B:~B() called.\n";}private:char *buf;};void main(){B b(10);}(2)#include<iostream.h>class A{public:A(int a,int b):x(a),y(b){cout<<"A constructor..."<<endl;}void Add(int a,int b){x+=a;y+=b;}void display(){cout<<"("<<x<<","<<y<<")"<<endl;}~A(){cout<<"destructor A..."<<endl;}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..."<<endl;}void Add(int x1,int y1,int x2,int y2){A::Add(x1,y1);i+=x2;j+=y2;}void display()A::display();Aobj.display();cout<<"("<<i<<","<<j<<")"<<endl;}~B(){cout<<"destructor B..."<<endl;}};void main(){B b(1,2,3,4);b.display();b.Add(1,3,5,7);b.display();}(3)#include<iostream.h>class A{public:A(int a):x(a){cout<<"A constructor..."<<x<<endl;}int f(){return ++x;}~A(){cout<<"destructor A..."<<endl;}private:int x;};class B:public virtual A{private:int y;A Aobj;public:B(int a,int b,int c):A(a),y(c),Aobj(c)cout<<"B constructor..."<<y<<endl;}int f(){A::f();Aobj.f();return ++y;}void display(){cout<<A::f()<<'\t'<<Aobj.f()<<'\t'<<f()<<endl;}~B(){cout<<"destructor B..."<<endl;}};class C:public B{public:C(int a,int b,int c):B(a,b,c),A(0){cout<<"C constructor..."<<endl;}};class D:public C,virtual public A{public:D(int a,int b,int c):C(a,b,c),A(c){cout<<"D constructor..."<<endl;}~D(){cout<<"destructor D..."<<endl;}};void main(){D d(7,8,9);d.f();d.display();}#include<iostream.h>class Base1{public:Base1(){cout<<"class Base1!"<<endl;}};class Base2{public:Base2(){cout<<"class Base2!"<<endl;}};class Level1:public Base2,virtual public Base1 {public:Level1(){cout<<"class Level1!"<<endl;}};class Level2:public Base2,virtual public Base1 {public:Level2(){cout<<"class Level2!"<<endl;}};class TopLevel:public Level1,virtual public Level2 {public:TopLevel(){cout<<"class TopLevel!"<<endl;}};void main(){TopLevel obj;}2.调试下列程序,并对程序进行修改后再调试,指出调试中的出错原因。

继承与派生类答案

继承与派生类知识要点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分析:一个派生类可以作为另一个派生类的基类。

继承与派生类答案

继承与派生类知识要点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++继承和派生编程参考答案

继承和派生练习一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;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验九派生与继承——构造与析构函数9.1 实验目的1.理解派生类中构造函数和析构函数及其调用顺序。

2、理解虚基类的应用。

9.2 实验内容9.2.1程序阅读1.理解下面的程序,并运行查看结果,回答程序后面的问题。

#include <iostream>using namespace std;class CBase{public:CBase(int a):a(a){}void print(){cout<<"a="<<a<<endl;}private:int a;};class CDerive : public CBase{public:CDerive(int a,int s):CBase(a){b=s;}void print(){cout<<"b="<<b<<endl;}int b;};int main(){CDerive d(3,4);d.print();//-----------------------------------------------------①CBase b(4);b.print();//-----------------------------------------------------②return 0;}问题一:请指出①与②两处的print函数调用有何区别?答:①处是调用派生类CDerive的成员函数,在派生类中函数print()与基类中的print()同名,所以它会覆盖基类重中的print()函数,在调用函数时执行派生类的print()函数;而②处是调用CBase类的成员函数。

问题二:修改程序,使程序能输出基类的数据成员a。

答:1、在①处后面增加代码d.CBase::print();2、在派生类的print函数中增加语句CBase::print();2.理解下面的程序,并运行查看结果,回答程序后面的问题。

#include <iostream>using namespace std;class CBase{public:CBase(int a):a(a){cout<<"base structure"<<endl;}~CBase(){cout<<"base destructure"<<endl;}void print(){cout<<"a="<<a<<endl;int a;};class CDerive : public CBase{public:CDerive(int a, int b,int c):CBase(a),b(b),c(c) //-----------------------------------------------------①{cout<<"derive structure"<<endl;}~CDerive(){cout<<"derive destructure"<<endl;}void print(){CBase::print();cout<<"b.a="<<b.a<<endl;cout<<"c="<<c<<endl;}private:CBase b;int c;};int main(){CDerive d(1,2,3); //-----------------------------------------------------②d.print();return 0;}问题一:请解释①处的含义?答:派生类构造函数先调用基类CBase的构造函数,对基类构造函数的数据成员初始化;,再调用子对象b的构造函数,对子类的数据成员初始化;最后执行派生类构造函数本身,对派生类数据成员c初始化。

问题二:②处语句执行完后,d.b.a的值为多少?答:2问题三:以上程序的输出结果是什么,说明为什么?答:因为派生类构造函数先调用基类CBase的构造函数,将基类构造函数的数据成员a初始化为1;,再调用子对象b的构造函数,将子类的数据成员a初始化为2;再执行派生类构造函数本身,将派生类数据成员c初始化为3;然后执行派生类的析构函数,接着是子类的析构函数,最后是基类的析构函数。

3.以下程序实现的继承关系如下图所示,理解下面的程序,并运行查看结果,回答程序后面的问题。

#include <iostream>#include <string>using namespace std;//声明公共基类Personclass Person{public:Person(string nam,char s,int a)//构造函数{name=nam;sex=s;age=a;}protected: //保护成员string name;char sex;int age;};//声明Person的直接派生类Teacherclass Teacher:public Person{public:Teacher(string nam,char s,int a, string t):Person(nam,s,a)//构造函数{title=t; }protected: //保护成员string title; };//声明Person的直接派生类Studentclass Student: public Person{public:Student(string nam,char s,int a,float sco) //构造函数:Person(nam,s,a),score(sco){ } //初始化表protected: //保护成员float score; //成绩};//声明多重继承的派生类Graduateclass Graduate:public Teacher,public Student //Teacher和Student为直接基类{public:Graduate(string nam,char s,int a, string t,float sco,float w)//构造函数:Person(nam,s,a),Teacher(nam,s,a,t),Student(nam,s,a,sco),wage(w){}//初始化表void show( ) //输出研究生的有关数据{cout<<"name:"<<name<<endl;cout<<"age:"<<age<<endl;cout<<"sex:"<<sex<<endl;cout<<"score:"<<score<<endl;cout<<"title:"<<title<<endl;cout<<"wages:"<<wage<<endl;}private:float wage; //工资};//主函数int main( ){Graduate grad1("Wang-li",'f',24,"assistant",89.5,1234.5);grad1.show( );return 0;}问题一:以上程序错误的原因是什么?请改正。

答:由于多重继承引起的的二义性,程序在执行函数show( )输出数据成员时无法区别是基类Person的成员,还是Teacher类从基类继承下来的成员,还是Student类从基类继承下来的成员;改正:应在Teacher类和Student 类继承基类前加关键字virtual使程序只保留一份成员:class Teacher:virtual public Personclass Student: virtual public Person问题二:请修改程序,在构造与析构函数中输出一些信息以理解对象建立的过程。

答:#include <iostream>#include <string>using namespace std;//声明公共基类Personclass Person{public:Person(string nam,char s,int a)//构造函数{name=nam;sex=s;age=a;cout<<"这是Person类的构造函数!"<<endl; }~Person(){cout<<"这是Person类的析造函数!"<<endl; }protected: //保护成员string name;char sex;int age;};//声明Person的直接派生类Teacherclass Teacher:virtual public Person{public:Teacher(string nam,char s,int a, string t):Person(nam,s,a)//构造函数{title=t;cout<<"这是Teacher类的构造函数!"<<endl; }~Teacher(){cout<<"这是Teacher类的析造函数!"<<endl; }protected: //保护成员string title; };//声明Person的直接派生类Studentclass Student: virtual public Person{public:Student(string nam,char s,int a,float sco) //构造函数:Person(nam,s,a),score(sco){cout<<"这是Student类的构造函数!"<<endl; } //初始化表~Student(){cout<<"这是Student类的析造函数!"<<endl; }protected: //保护成员float score; //成绩};//声明多重继承的派生类Graduateclass Graduate:public Teacher,public Student //Teacher和Student为直接基类{public:Graduate(string nam,char s,int a, string t,float sco,float w)//构造函数:Person(nam,s,a),Teacher(nam,s,a,t),Student(nam,s,a,sco),wage(w){cout<<"这是Graduate类的构造函数!"<<endl; }//初始化表~Graduate(){cout<<"这是Graduate类的析造函数!"<<endl; }void show( ) //输出研究生的有关数据{cout<<"name:"<<name<<endl;cout<<"age:"<<age<<endl;cout<<"sex:"<<sex<<endl;cout<<"score:"<<score<<endl;cout<<"title:"<<title<<endl;cout<<"wages:"<<wage<<endl;}private:float wage; //工资};//主函数int main( ){Graduate grad1("Wang-li",'f',24,"assistant",89.5,1234.5);grad1.show( );return 0;}9.2.2 程序设计1.定义点CPoint类作为基类,在此基础上派生出直线CLine类和圆CCircle类,并要求基类和各派生类具有以下特点:a.CLine类含有计算直线长度和斜率的成员函数;b.CCircle类含有计算圆面积的成员函数。

相关文档
最新文档