第12章继承与派生主观题目和客观题目林华文档格式.docx
《第12章继承与派生主观题目和客观题目林华文档格式.docx》由会员分享,可在线阅读,更多相关《第12章继承与派生主观题目和客观题目林华文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
e=e1}
intgetB_d(){returnd;
intgetB_e(){returne;
2、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
portectedA{
3、根据下列代码,写出派生类Y所含的成员及成员的访问控制属性
classBASE{
BASE(){i=1;
j=2;
xtemp=3;
}
voidget_xtemp(){get_ij();
cout<
<
"
(BASE)xtemp="
xtemp<
endl;
protected:
inti,j;
voidget_ij(){cout<
(BASE)i="
i<
(BASE)j="
j<
private:
intxtemp;
};
classY:
publicBASE{
Y(){k=4;
xtemp=5;
voidget_temp(){cout<
(Y)i="
(Y)j="
cout<
(Y)k="
k<
cout<
(Y)xtemp="
get_ij();
}
doublek;
voidget_xtemp(){cout<
get_xtemp()inY…"
}
doublextemp;
4、根据下列代码,写出派生类Y所含的成员及成员的访问控制属性
protectedBASE{
5、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
classA
{
intax;
intay;
intaz;
intGetax(){returnax;
voidSetax(intx){ax=x;
classB:
publicA
intbx;
intby;
intbz;
intGetbz(){returnbz;
voidSetbz(intz){bz=z;
6、根据下列代码,写出派生类B所含的成员及成员的访问控制属性
protectedA
三、填空题
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访问限定符基类类名{...};
访问限定符virtual基类类名{...};
4、比较类的三种继承方式public(公有继承)、protected(保护继承)、private(私有继承)之间的差别。
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:
基类的private成员在派生类中不可见。
区别:
对于私有继承,基类的public,protected成员在派生类中作为private成员;
对于公有继承,基类的public,protected成员在派生类中访问属性不变;
对于保护继承,基类的public,protected成员在派生类中作为protected成员。
5、简单叙述派生类与基类的赋值兼容规则。
凡是基类所能解决的问题,公有派生类都可以解决。
在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称赋值兼容规则。
它包括以下情况:
1.派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的成员赋值给基类对象。
反过来不行,因为派生类的新成员无值可赋。
2.可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,不能访问派生类中的新成员。
同样也不能反过来做。
派生类对象可以初始化基类的引用。
引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。
6、什么是派生类与基类的赋值兼容规则?
派生类与基类的赋值兼容规则:
可以将公有派生类对象赋值给基类对象,反之是不允许的。
五、阅读程序,分析类间关系及写出执行结果:
1、写出下面程序的输出
#include<
iostream.h>
class
base
{
intn;
base(){};
base(inta)
{
cout<
"
constructingbaseclass"
<
endl;
n=a;
n="
n<
~base()
{cout<
destructingbaseclass"
classsubs:
publicbase
intm;
subs(inta,intb)
:
base(a)
constructingsubclass"
m=b;
cout
m="
m<
subs()
destructingsubclass"
voidmain()
subss(1,2);
这里base是基类,subs为派生类,subs类的构造函数中含有调用基本类的构造函数。
所以输出为:
constructingbaseclass
n=1
constructingsubclass
n=2
destructingbaseclass
destructingsubclass
2、写出下面程序的输出
#include<
A(inti)
{a=i;
cout<
constructingclassA"
voidprint()
a<
~A()
destructingclassA"
classBi:
publicA
intbl;
Bl(inti,intj):
A(i)
bl=j;
constructingclassBI"
voidprint()
A:
:
print();
bl<
~BI(){cout<
destructingclassBI"
classB2:
intb2;
B2(inti,intj):
A(i);
b2=j;
constructingclassB2"
b2<
~B2(){cout<
destructingclassB2"
classC:
publicB1,publicB2
intc;
C(inti,intj,intk,int1,intm):
Bl(i,j),B2(k,1),c(m)
constructingclassC"
Bl:
print();
B2:
c<
~C(){cout<
destructingclassC"
voidmain()
Cc1(1,2,3,4,5);
cl.print();
C类是从B1类和B2类派生的,而B1和B2类又都是从A类派生,但各有自己的副本,所有这些成员函数均有print()成员函数。
所以,在C的成员函数实现中,调用print()时,要加上类作用域运算符“:
:
”。
constructingclassA
constructingclassB1
constructingclassB2
constructingclassC
1
2
3
4
5
destructingclassC
destructingclassB2
destructingclassA
destructingclassB1
3、写出下面程序的输出
A(char*s)
s<
~A(){}
B(char*sl,char*s2):
A(sl)
s2<
C(char*sl,char*s2):
classD:
publicB,publicC
D(char*sl,char*s2,char*s3,char*s4):
B(sl,s2),C(sl,s3)
s4<
Dd("
classA"
"
classB"
classC"
classD"
);
D类是从B和C类派生的,而B和C类又都是从A类派生,但各有自己的副本。
classB
classC
classD
4、写出下面程序的输出
A(){cout<
\nThisisAclass.\n"
;
B(){cout<
ThisisBclass.\n"
classderivedA:
publicB,virtualpublicA
public:
derivedA(){cout<
ThisisderivedAclass.\n"
classderivedB:
publicB,virtualpublicA
derivedB(){cout<
ThisisderivedBclass.\n"
classDerived:
publicderivedA,virtualpublicderivedB
Derived(){cout<
ThisisDerivedclass.\n"
};
intmain()
Derivedobj;
return1;
derivedA类和derivedB类都是从虚基类A和基类B派生的,而Derived类又从derivedA类和虚基类derivedB派生,但各有自己的副本。
ThisisAclass.
ThisisBclass.
ThisisderivedBclass.
ThisisderivedAclass.
ThisisDerivedclass.
5、写出下面程序的输出
classBase
{inti;
Base(intn){cout<
Constuctingbaseclass"
i=n;
~Base(){cout<
Destructingbaseclass"
voidshowi(){cout<
i<
intGeti(){returni;
publicBase
{intj;
Baseaa;
Derived(intn,intm,intp):
Base(m),aa(p){
Constructingderivedclass"
j=n;
~Derived(){cout<
Destructingderivedclass"
voidshow(){Base:
showi();
j<
aa.Geti()<
{Deri