Return0;
}
答案:
57
2继承与派生
2.1填空题
(1)面向对象程序设计的继承机制实现了代码重用,有效地缩短了程序的开发周期。
(2)在继承关系中,被继承的类成为基类,通过继承关系定义出来的新类称为
派生类。
(3)派生类的继承方式有private、protected和public3种,其中默认的继承方式为private。
(4)公有继承时,基类的私有成员成为派生类的不可访问成员,基类的保护成员成为派生类的保护成员,基类的公有成员成为派生类的公有成员。
(5)在派生类中不能访问基类的私有成员,这符合面向对象程序设计的封装思想。
(6)C++语言不仅支持单
(一)继承,也支持多(重)继承。
(7)根据联编实现的不同阶段,可将其分为静态联编和动态联编两种。
(8)声明了纯虚函数的类,称为抽象类。
(9)运算符重载是一种特殊的函数重载
(10)对于运算符的重载可以有__重载为类的成员函数___和___重载为类的友元函数__两种方法。
(11)__Operator__和运算符一起可以组成运算符函数的函数名。
(12)对于双目运算符,若重载为类的成员函数,有__1___个参数;若重载为友元函数,则有__2___个参数。
(13)运算符[]不能作为类的__友元___函数重载。
2.2选择题
(1)下列关于派生类的描述中,不正确的是(B)。
A派生类的成员除了包含它自己的成员外,还包含其基类的成员。
B派生类中继承的基类的成员的访问权限在派生类中保持不变。
C派生类至少有一个基类。
D一个派生类可以作为另一个派生类的基类
(2)在保护继承中,基类的私有成员变成派生类的(A)
A不可访问成员B私有成员C保护成员D公有成员
(3)若有如下类声明:
ClassBase
{intk;
public:
voidset(intn){k=n;}
intget()const{returnk;}
};
Classderived:
protectedBase
{
protected:
intj;
public:
voidset(intm,intn)
{Base:
:
set(m);
j=n;
}
intget()const
{returnbase:
:
get()+j;
}
};
则类derived中保护的数据成员和成员函数的个数是(B)。
A4B3C2D1
(4)在派生类的构造函数的初始化表中,不能包含(C)。
A基类的构造函数B派生类的一般数据成员的初始化
C基类的子对象的初始化D派生类的子对象的初始化
(5)若有如下类声明:
ClassX
{intx;
public:
X(intn){x=n;}
};
ClassY:
publicX
{inty;
public:
Y(inta,intb);
};
在构造函数Y的下列定义中,正确的是(B)。
AY:
:
Y(inta,intb):
x(a),y(b){}BY:
:
Y(inta,intb):
X(a),y(b){}
CY:
:
Y(inta,intb):
x(a)Y(b){}DY:
:
Y(inta,intb):
X(a),Y(b){}
(6)在多重继承中,对于基类成员在派生类中的访问权限与单继承的规则(A)。
A完全相同B完全不同C部分相同D以上均不正确
(7)下列说法中不正确的是(D)。
A私有继承时,基类的公有成员在派生中是私有成员
B保护继承时,基类的公有成员在派生中是保护成员
C公有继承时,基类的公有成员在派生中是公有成员
D公有继承时,基类的私有成员在派生中是私有成员
(8)下列描述中不正确的是(B)。
A派生类的对象可以赋值给基类对象
B基类的对象可以赋值给派生类对象
C派生类的对象可以初始化为基类的引用
D派生类的对象的地址可以赋给指向基类的指针
(9)下列关于虚基类的描述中,不正确的是(B)。
A使用虚基类的目的是消除多重继承下的二义性
B虚基类中的子对象的初始化次数与该虚基类的派生类的个数有关
C虚基类中的子对象只初始化一次
D虚基类的多层派生类构造函数的成员初始化列表中都要列出对虚基类构造函数的调用
(10)运行时的多态性是指(B)。
A用指向对象的基类指针或引用调用一个纯虚函数
B用指向对象的基类指针或引用调用一个虚函数
C以任何方式调用一个纯虚函数
D以任何方式调用一个虚函数
(11)在C++中,用于实现运行时多态性的是(D)。
A内联函数B重载函数C模板函数D虚函数
(12)下列关于虚函数的描述中,正确的是(B)。
A从虚基类继承的函数都是虚函数B虚函数不得是静态成员函数
C只能通过指针或引用调用虚函数D抽象类中的成员函数都是虚函数
(13)下列关于运算符重载的描述中,正确的是(B)。
A)通过运算符重载,可以定义新的运算符
B)有的运算符只能作为成员函数重载
C)若重载运算符+,则相应的运算符函数名是+
D)重载一个二元运算符时,必须声明两个形参
(14)下列表达式中,运算符“/”的意义相同的一对是(D)。
A)3/2和3.0/2.0B)3/2和3/2.0
C)3/2和3.0/2D)3.0/2.0和3.0/2
(15)在重载一个运算符时,其函数的参数表中没有任何参数,这说明该运算符是(A)。
A)一元成员运算符B)二元成员运算符
C)一元友元运算符D)二元友元运算符
(16)以下运算符中既可以重载为类的成员函数,又可以重载为类的友元函数的是(D)。
A)=B)()C)[]D)++
(17)已知在一个类体中包含如下函数原型:
Xoperator-(X)const;
下列关于这个函数的描述中,不正确的是(B)。
A)这是运算符-的重载运算符函数
B)这个函数所重载的运算符是一个一元运算符
C)这是一个成员函数
D)这个函数不改变类的任何数据成员的值
(18)在表达式x+y*z中,+是作为成员函数重载的运算符,*是作为友元函数重载的运算符。
下列描述中正确的是(C)。
A)operator+有两个参数,operator*有两个参数
B)operator+有两个参数,operator*有一个参数
C)operator+有一个参数,operator*有两个参数
D)operator+有一个参数,operator*有一个参数
(19)运算符重载是对已有的运算符赋予多重含义,下列描述中正确的是(C)。
A)可以对基本类型(如int类型)的数据,重新定义“+”运算符的含义
B)可以改变一个已有运算符的优先级和操作个数
C)只能重载C++中已有的运算符,不能定义新运算符
D)C++中已有的所有运算符都可以重载
2.3改错题
(1)
#include
classA
{public:
inta1;
protected:
inta2;
private:
inta3;
};
classB:
publicA
{public:
intb1;
voidfb();
protected:
intb2;
private:
intb3;
};
voidB:
:
fb()
{a1=10;a2=20;a3=30;
b1=100;b2=100;b3=100;
}
voidmain()
{Ax;
By;
x.a1=10;x.a2=20;x.a3=30;
y.a1=100;y.a2=200;y.a3=300;
y.b1=1000;y.b2=2000;y.b3=3000;
}
本题的错误主要是数据成员的访问权限问题:
基类的私有成员在派生类中不可访问,如fb()函数中的a3=30;语句;类的私有和保护成员在类外不能访问,如main函数中的x.a2=20;.a3=30;,y.a2=200;,y.a3=300;,y.b2=2000;和y.b3=3000;语句。
(2)
#include
usingnamespacestd;
classbase
{private:
voidfun1()const{cout<<”fun1”;}
protected:
voidfun2()const{cout<<”fun2”;}
public:
voidfun3()const{cout<<”fun3”;}
};
classderived:
protectedbase
{public:
voidfun4()const{cout<<”fun4”;}
};
intmain()
{derivedobj;
obj.fun1();
obj.fun2();
obj.fun3();
obj.fun4();
return0;
}
本题的错误主要是成员函数的访问权限问题:
由于派生类Derived是基类Base的保护派生类,所以基类中的私有成员变成派生类的不可访问成员,而基类的保护和公有成员则变成派生类的保护成员。
对于类的不可访问和保护成员在类外是不能访问的,故main函数中的语句obj.funl();,obj.fun2();和obj.fun3();是错误的。
2.4读程序写结果题
(1)
#include
classB
{public:
B(inti){b=i-10;}
B(){b=0;}
virtualvoidshow()
{cout<<”b=”<
prot