第12章继承与派生主观题目和客观题目林华.docx
《第12章继承与派生主观题目和客观题目林华.docx》由会员分享,可在线阅读,更多相关《第12章继承与派生主观题目和客观题目林华.docx(26页珍藏版)》请在冰豆网上搜索。
![第12章继承与派生主观题目和客观题目林华.docx](https://file1.bdocx.com/fileroot1/2023-2/4/61907b9c-b2f3-40ea-96b3-6a7d8df2539d/61907b9c-b2f3-40ea-96b3-6a7d8df2539d1.gif)
第12章继承与派生主观题目和客观题目林华
一、继承与派生的编程题:
1、Box类包含三个私有数据成员a(立方体边长)、volume(体积)和area(表面积),另有两个构造函数以及seta()(设置立方体边长)、getvolume()(计算体积)、getarea(计算表面积)和disp(输出结果)。
请声明并实现该类,并写出主函数进行测试,长方体的参数要求从键盘输入,并输出其表面积和体积。
2、设计一个长方形类(Rectangle),包含两个私有的数据成员length,width,要求能求其面积;再从Rectangle派出一个长方体(Volume),要求能求其体积。
请声明并实现这两个类,并在主函数中分别定义这两个类的对象,并打印出相应的面积和体积。
3、定义一个物体基类object,有数据成员重量weight,有构造函数对数据成员weight进行初始化,有成员函数打印重量信息PrintWeight。
从object类派生出盒子类box,增加数据成员高度heigh和宽度width,并定义派生类box类的构造函数对数据成员weight、height、width进行初始化,有成员函数PrintAll打印数据成员weight、height、width值。
在主函数中创建一个box对象,并初始化其所有数据成员,调用成员函数将weight、height、width值信息显示。
4、自行车(Bicycle)和汽车(Motorcar)都是车辆(Vehicle),它们有共同的属性最大速度(maxSpeed)和重量(weight),也有各自不同的特性,比如自行车的高度(height)和汽车的座位数(seatNum)。
现有车辆若干(设N=3),将其输入并放入一个指针数组,每个车辆需要设置其属性。
输入后分类显示各自属性(即自行车和汽车分别显示各自属性)。
5、定义Point作为基类,在此基础上派生出圆Circle类,该类含有计算面积的成员函数,并由Circle类派生出圆柱Cylinder类,该类含有计算柱体的表面积和体积的成员函数。
6、编写程序定义人员类Person作为基类,其数据成员为姓名和身份号,在此基础上派生出职员Employee类,该类的数据成员为底薪和工作年数,含有实现相关信息输入和输出的成员函数以及计算并显示奖金和月薪的成员函数。
计算办法:
奖金=10*工作年数,月薪=底薪+奖金。
二、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
1、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
classA{
private:
inta;
protected:
intb;
public:
A(inta1=0,intb1=0){a=a1;b=b1}
intgetA_a(){returna;}
intgetA_b(){returnb;}
};
classB:
publicA{
private:
intd;
protected:
inte;
public:
B(intd1=0,inte1=0){d=d1;e=e1}
intgetB_d(){returnd;}
intgetB_e(){returne;}
};
2、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
classA{
private:
inta;
protected:
intb;
public:
A(inta1=0,intb1=0){a=a1;b=b1}
intgetA_a(){returna;}
intgetA_b(){returnb;}
};
classB:
portectedA{
private:
intd;
protected:
inte;
public:
B(intd1=0,inte1=0){d=d1;e=e1}
intgetB_d(){returnd;}
intgetB_e(){returne;}
};
3、根据下列代码,写出派生类Y所含的成员及成员的访问控制属性
classBASE{
public:
BASE(){i=1;j=2;xtemp=3;}
voidget_xtemp(){get_ij();
cout<<"(BASE)xtemp="<}
protected:
inti,j;
voidget_ij(){cout<<"(BASE)i="<
cout<<"(BASE)j="<}
private:
intxtemp;
};
classY:
publicBASE{
public:
Y(){k=4;xtemp=5;}
voidget_temp(){cout<<"(Y)i="<
cout<<"(Y)j="<cout<<"(Y)k="<cout<<"(Y)xtemp="<get_ij();
}
protected:
doublek;
voidget_xtemp(){cout<<"get_xtemp()inY…"<private:
doublextemp;
};
4、根据下列代码,写出派生类Y所含的成员及成员的访问控制属性
classBASE{
public:
BASE(){i=1;j=2;xtemp=3;}
voidget_xtemp(){get_ij();
cout<<"(BASE)xtemp="<}
protected:
inti,j;
voidget_ij(){cout<<"(BASE)i="<
cout<<"(BASE)j="<}
private:
intxtemp;
};
classY:
protectedBASE{
public:
Y(){k=4;xtemp=5;}
voidget_temp(){cout<<"(Y)i="<
cout<<"(Y)j="<cout<<"(Y)k="<cout<<"(Y)xtemp="<get_ij();
}
protected:
doublek;
voidget_xtemp(){cout<<"get_xtemp()inY…"<private:
doublextemp;
};
5、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
classA
{
private:
intax;
protected:
intay;
public:
intaz;
intGetax(){returnax;}
voidSetax(intx){ax=x;}
};
classB:
publicA
{
private:
intbx;
protected:
intby;
public:
intbz;
intGetbz(){returnbz;};
voidSetbz(intz){bz=z;};
};
6、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
classA
{
private:
intax;
protected:
intay;
public:
intaz;
intGetax(){returnax;}
voidSetax(intx){ax=x;}
};
classB:
protectedA
{
private:
intbx;
protected:
intby;
public:
intbz;
intGetbz(){returnbz;};
voidSetbz(intz){bz=z;};
};
三、填空题
1、如果类α继承了类β,则类α称为
(1)类,而类β称为
(2)类。
(3)类的对象可作为(4)类的对象处理,反过来不行,因为(5)。
如果强制转换则要注意(6)。
答案:
(1)基类
(2)派生类
(3)派生类
(4)基类
(5)派生类有一些新成员
(6)只能派生类强制转换为基类
2、当用public继承从基类派生一个类时,基类的public成员成为派生类的
(1)成员,protected成员成为派生类的
(2)成员,对private成员是(3)。
公有派生可以使其类的(4),所以公有派生是主流。
答案:
(1)public成员
(2)protected成员
(3)不可访问
(4)接口不变
3、利用继承能够实现
(1)。
这种实现缩短了程序开发的时间,VC++中的
(2)很好地体现了这一点。
答案:
(1)代码的复用
(2)MFC编程
4、一个派生类只有一个直接基类的情况称为
(1),而有多个直接基类的情况称为
(2)。
继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。
答案:
(1)单继承/单一继承
(2)多继承/多重继承
(3)层次
(4)单继承/单一继承
5、生成一个派生类对象时,先调用
(1)的构造函数,然后调用
(2)的构造函数。
答案:
(1)基类/虚基类
(2)派生类
6、继承发生在利用已有类派生新类时,其中
(1)称为基类,或
(2)类;(3)称为派生类,或(4)类。
答案:
(1)已有类
(2)父
(3)新类
(4)子
7、在公有继承关系下,派生类的对象可以访问基类中的
(1)成员,派生类的成员函数可以访问基类中的
(2)成员。
答案:
(1)公有/public
(2)公有和保护/publicandprotected
8、在保护继承关系下,基类的公有成员和保护成员将成为派生类中的
(1)成员,它们只能由派生类的
(2)来访问;基类的私有成员将成为派生类中的(3)成员。
答案:
(1)保护成员/protected
(2)成员函数
(3)不可访问
四、简答题
1、构造函数和析构函数可以继承吗?
派生类构造函数各部分的执行次序是怎样的?
答:
构造函数和析构函数不可以继承。
派生类构造函数各部分的执行次序是:
1.调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。
2.调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。
3.派生类的构造函数体中的操作。
2、派生类的析构函数中需完成什么任务?
是否要编写对基数和成员对象的析构函数的调用?
为什么?
答:
析构函数的功能用于撤销该对象时做清理工作,析构函数无返回类型也没有参数,情况比较简单。
派生类析构函数定义格式与非派生类无任何差异,不要编写对基数和成员对象的析构函数的调用,只要在函数体内把派生类新增一般成员处理好就可以了,因为对新增的成员对象和基类的善后工作,系统会自己调用成员对象和基类的析构函数来完成。
3、为什么要使用虚基类?
怎样定义虚基类?
答:
在多重继承是有可能出现同一基类的两个拷贝,为避免这种情况,可使用虚基类。
虚基类(virtualbaseclass)定义方式如下:
class派生类名:
virtual访问限定符基类类名{...};
class派生类名:
访问限定符virtual基类类名{...};
4、比较类的三种继承方式public(公有继承)、protected(保护继承)、private(私有继承)之间的差别。
答:
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:
基类的private成员在派生类中不可见。
区别:
对于私有继承,基类的public,protected成员在派生类中作为private成员;对于公有继承,基类的public,protected成员在派生类中访问属性不变;对于保护继承,基类的public,protected成员在派生类中作为protected成员。
5、简单叙述派生类与基类的赋值兼容规则。
答:
凡是基类所能解决的问题,公有派生类都可以解决。
在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称赋值兼容规则。
它包括以下情况:
1.派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的成员赋值给基类对象。
反过来不行,因为派生类的新成员无值可赋。
2.可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,不能访问派生类中的新成员。
同样也不能反过来做。
派生类对象可以初始化基类的引用。
引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。
6、什么是派生类与基类的赋值兼容规则?
答:
派生类与基类的赋值兼容规则:
可以将公有派生类对象赋值给基类对象,反之是不允许的。
五、阅读程序,分析类间关系及写出执行结果:
1、写出下面程序的输出
#include
class base
{
intn;
public:
base(){};
base(inta)
{
cout<<"constructingbaseclass" < n=a;
cout<< "n=" < }
~base() {cout<<"destructingbaseclass"<};
classsubs:
publicbase
{
intm;
public:
subs(inta,intb) :
base(a)
{
cout<<"constructingsubclass" < m=b;
cout << "m=" < }
subs() {cout<<"destructingsubclass"<};
voidmain()
{
subss(1,2);
}
答:
这里base是基类,subs为派生类,subs类的构造函数中含有调用基本类的构造函数。
所以输出为:
constructingbaseclass
n=1
constructingsubclass
n=2
destructingbaseclass
destructingsubclass
2、写出下面程序的输出
#include
classA
{
inta;
public:
A(inti) {a=i;cout<<"constructingclassA"< voidprint() {cout< ~A() {cout<<"destructingclassA"<};
classBi:
publicA
{
intbl;
public:
Bl(inti,intj):
A(i)
{
bl=j;cout<<"constructingclassBI"< voidprint()
{
A:
:
print();
cout< }
~BI(){cout<<"destructingclassBI"<};
classB2:
publicA
{
intb2;
public:
B2(inti,intj):
A(i);
{
b2=j;cout<<"constructingclassB2"< }
voidprint()
{
A:
:
print();
cout< }
~B2(){cout<<"destructingclassB2"<};
classC:
publicB1,publicB2
{
intc;
public:
C(inti,intj,intk,int1,intm):
Bl(i,j),B2(k,1),c(m)
{
cout<<"constructingclassC"< }
voidprint()
{
Bl:
:
print();
B2:
:
print();
cout< }
~C(){cout<<"destructingclassC"<};
voidmain()
{
Cc1(1,2,3,4,5);
cl.print();
}
答:
C类是从B1类和B2类派生的,而B1和B2类又都是从A类派生,但各有自己的副本,所有这些成员函数均有print()成员函数。
所以,在C的成员函数实现中,调用print()时,要加上类作用域运算符“:
:
”。
所以输出为:
constructingclassA
constructingclassB1
constructingclassA
constructingclassB2
constructingclassC
1
2
3
4
5
destructingclassC
destructingclassB2
destructingclassA
destructingclassB1
destructingclassA
3、写出下面程序的输出
#include
classA
{
public:
A(char*s) {cout<
~A(){}
};
classB:
publicA
{
public:
B(char*sl,char*s2):
A(sl)
{
cout< }
};
classC:
publicA
{
public:
C(char*sl,char*s2):
A(sl)
{
cout< }
};
classD:
publicB,publicC
{
public:
D(char*sl,char*s2,char*s3,char*s4):
B(sl,s2),C(sl,s3)
{
cout< }
voidmain()
{
Dd("classA","classB","classC","classD");
}
答:
D类是从B和C类派生的,而B和C类又都是从A类派生,但各有自己的副本。
所以输出为:
classA
classB
classA
classC
classD
4、写出下面程序的输出
#include
classA
{
public:
A(){cout<<"\nThisisAclass.\n";}
};
classB
{
public:
B(){cout<<"ThisisBclass.\n";}
};
classderivedA:
publicB,virtualpublicA
{
public:
derivedA(){cout<<"ThisisderivedAclass.\n";}
};
classderivedB:
publicB,virtualpublicA
{
public:
derivedB(){cout<<"ThisisderivedBclass.\n";}
};
classDerived:
publicderivedA,virtualpublicderivedB
{
public:
Derived(){cout<<"ThisisDerivedclass.\n";}
};
intmain()
{
Derivedobj;
return1;
}
答:
derivedA类和derivedB类都是从虚基类A和基类B派生的,而Derived类又从derivedA类和虚基类derivedB派生,但各有自己的副本。
所以输出为:
ThisisAclass.
ThisisBclass.
ThisisderivedBclass.
ThisisBclass.
ThisisderivedAclass.
ThisisDerivedclass.
5、写出下面程序的输出
#include
classBase
{inti;
public:
Base(intn){cout<<"Constuctingbaseclass"<~Base(){cout<<"Destructingbaseclass"<voidshowi(){cout<
intGeti(){returni;}
};
classDerived:
publicBase
{intj;
Baseaa;
public:
Derived(intn,intm,intp):
Base(m),aa(p){
cout<<"Constructingderivedclass"<j=n;
}
~Derived(){cout<<"Destructingderivedclass"<voidshow(){Base:
:
showi();
cout<};
voidmain()
{Deri