1-1
虚函数是用virtual 关键字说明的成员函数。 T
1-2
动态绑定是在运行时选定调用的成员函数的。 T
1-3
构造函数可以声明为虚函数。F
1-4
构造函数可以声明为纯虚函数。F
1-5
虚函数不能是类的静态成员。T
1-6
重定义虚函数的派生类必须是公有继承的。T
1-7
作为虚函数隐含参数的this指针,决定了虚函数调用时执行的代码。T
2-1
关于纯虚函数和抽象类的描述中,(C )是错误的。
A. 纯虚函数是一种特殊的虚函数,它没有具体的实现
B. 抽象类是指具有纯虚函数的类
C. 一个基类中说明有纯虚函数,该基类的派生类一定不再是抽象类
D. 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出
2-2
虚析构函数的作用是。 C
A. 虚基类必须定义虚析构函数
B. 类对象作用域结束时释放资源
C. delete动态对象时释放资源
D. 无意义
2-3
在派生类中,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值。 A
A. 相同
B. 不同
C. 相容
D. 部分相同
2-4
若一个类中含有纯虚函数,则该类称为。 C
A. 基类
B. 纯基类
C. 抽象类
D. 派生类
2-5
假设 Aclass为抽象类,下列正确的说明语句是。 B
A. Aclass fun( int ) ;
B. Aclass * p ;
C. int fun( Aclass ) ;
D. Aclass Obj ;
2-6
关于动态绑定的下列描述中,(D )是错误的。
A. 动态绑定是以虚函数为基础的
B. 动态绑定在运行时确定所调用的函数代码
C. 动态绑定调用函数操作是通过指向对象的指针或对象引用来实现的
D. 动态绑定是在编译时确定操作函数的
4-1
Virtual functions overcome the problems with the type-field solution by allowing the programmer to declare functions in a base class that can be redefined in each derived class. The compiler and linker will guarantee the correct correspondence between objects and the functions applied to them.
6-1 汽车收费
现在要开发一个系统,管理对多种汽车的收费工作。
给出下面的一个基类框架
class Vehicle
{
protected:
string NO;public:
Vehicle(string n){
NO = n;
}
virtual int fee()=0;//计算应收费用
};
以Vehicle为基类,构建出Car、Truck和Bus三个类。
Car的收费公式为: 载客数8+重量2
Truck的收费公式为:重量5
Bus的收费公式为: 载客数3
生成上述类并编写主函数
主函数根据输入的信息,相应建立Car,Truck或Bus类对象,对于Car给出载客数和重量,Truck给出重量,Bus给出载客数。假设载客数和重量均为整数
输入格式:第一行输入测试用例数。接着每个测试用例占一行,每行给出汽车的基本信息,第一个数据为当前汽车的类型:1为car,2为Truck,3为Bus。第二个数据为它的编号,接下来Car是载客数和重量,Truck要求输入重量,Bus要求输入载客数。
要求输出各车的编号和收费。
裁判测试程序样例:
#include
#include
using namespace std;
class Vehicle
{
protected:
string NO;//编号
public:
Vehicle(string n){ NO = n; }
virtual int fee()=0;//计算应收费用
};
int main()
{
Car c("",0,0);
Truck t("",0);
Bus b("",0);
int i, repeat, ty, weight, guest;
string no;
cin>>repeat;
for(i=0;i
cin>>ty>>no;
switch(ty){
case 1: cin>>guest>>weight; c=Car(no, guest, weight); cout<>weight; t=Truck(no, weight); cout<>guest; b=Bus(no, guest); cout<
仅供参考
class Car:public Vehicle{
public:
int guest;
int weight;
Car(string Number,int g,int w):Vehicle(Number){
guest = g;
weight = w;
}
int fee(){
return guest*8+weight*2;
}
};
class Truck:public Vehicle{
public:
int weight;
Truck(string Number,int w):Vehicle(Number){
weight = w;
}
int fee(){
return weight * 5;
}
};
class Bus:public Vehicle{
public:
int guest;
Bus(string Number,int g):Vehicle(Number){
guest = g;
}
int fee(){
return guest * 3;
}
};
6-2 抽象类Shape
15.抽象类Shape
请编写一个抽象类Shape,包括两个纯虚函数,分别为计算面积getArea()和计算周长getPerim()。通过Shape类派生出矩形类Rectangle和圆类Circle,并计算各自的面积和周长。
测试用例具体要求:输入1表示测试矩形类,之后输入矩形长和宽。输入2表示测试圆类,之后输入圆半径。
Shape类定义如下:
class Shape {
public:
virtual double getArea()=0;
virtual double getPerim()=0;
};
裁判测试程序样例:
#include
using namespace std;
const double PI=3.14;
class Shape {
public:
virtual double getArea()=0;
virtual double getPerim()=0;
};
int main() {
Shape *p;
int n;
double w,h,r;
scanf("%d",&n);
switch(n) {
case 1: {
cin>>w>>h;
Rectangle rect(w,h);
cout<<“area=”<
cin>>r;
Circle c®;
cout<<“area=”<
仅供参考
class Rectangle : public Shape{
private:
double width;
double height;
public:
Rectangle(double w, double h){
width = w;
height = h;
}
double getArea(){
return width * height;
}
double getPerim(){
return (width + height) * 2;
}
};
class Circle : public Shape{
private:
double radius;
public:
Circle(double r){
radius = r;
}
double getArea(){
return PI * radius * radius;
}
double getPerim(){
return (PI * radius) * 2;
}
};
6-3 虚函数的应用
6-3 虚函数的应用
补充下列代码,使得程序的输出为:
A:3
A:15
B:5
3
15
5
类和函数接口定义:
参见裁判测试程序样例中的类和函数接口。
裁判测试程序样例:
#include
using namespace std;
class CMyClassA {
int val;
public:
CMyClassA(int);
void virtual print();
};
CMyClassA::CMyClassA(int arg) {
val = arg;
printf(“A:%dn”, val);
}
void CMyClassA::print() {
printf("%dn", val);
return;
}
int main(int argc, char** argv) {
CMyClassA a(3), *ptr;
CMyClassB b(5);
ptr = &a;
ptr->print();
a = b;
a.print();
ptr = &b;
ptr->print();
return 0;
}
输入样例:
None
输出样例:
A:3
A:15
B:5
3
15
5
仅供参考
class CMyClassB :public CMyClassA {
public:
int val2;
CMyClassB(int x) :CMyClassA(3 * x), val2(x) {
printf("B:%dn", val2);
}
void print() {
printf("%dn", val2);
}
};
11+
选择题
2-1 D
关于动态绑定的下列描述中,( )是错误的。
A.动态绑定是以虚函数为基础的
B.动态绑定在运行时确定所调用的函数代码
C.动态绑定调用函数操作是通过指向对象的指针或对象引用来实现的
D.动态绑定是在编译时确定操作函数的
2-2 C
关于虚函数的描述中,( )是正确的。
A.虚函数是一个static 类型的成员函数
B.虚函数是一个非成员函数
C.基类中说明了虚函数后,派生类中与其对应的函数可不必说明为虚函数
D.派生类的虚函数与基类的虚函数具有不同的参数个数和类型
2-3 C
在C++语言中设置虚基类的目的是( ) 。
A.简化程序代码
B.提高程序的运行效率
C.解决多继承造成的二义性问题
D.缩短程序的目标代码
2-4 C
虚析构函数的作用是。
A.虚基类必须定义虚析构函数
B.类对象作用域结束时释放资源
C.delete动态对象时释放资源
D.无意义
程序填空题
5-1
文件目录树
分数 10
作者 张德慧
单位 西安邮电大学
阅读下列说明和C++代码,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】现欲构造一文件/目录树,采用组合(Composite)设计模式来设计,得到的类图如下所示
【C++代码】
#include
#include
#include
using namespace std;
class AbstractFile {
protected :
string name; // 文件或目录名称
public:
void printName(){cout << name;} // 打印文件或目录名称
virtual void addChild(AbstractFile *file)=0; // 给一个目录增加子目录或文件
virtual void removeChild(AbstractFile *file)=0;// 删除一个目录的子目录或文件
virtual list *getChildren()=0;// 获得一个目录的子目录或文件
};
class File : public AbstractFile {
public :
File(string name) {
this->name
= name; }
void addChild(AbstractFile *file) { return ; }
void removeChild(AbstractFile *file) { return ; }
list *
getChildren() { return
NULL
; }
};
class Folder :public AbstractFile {
private :
list childList; // 存储子目录或文件
public :
Folder(string name) {
this->name
= name; }
void addChild(AbstractFile *file) { childList.push_back(file); }
void removeChild(AbstractFile *file) { childList.remove(file);}
list *getChildren() { return
NULL
; }
};
int main( ) {
// 构造一个树形的文件/目录结构
AbstractFile *rootFolder = new Folder("c:\");
AbstractFile *compositeFolder = new Folder("composite");
AbstractFile *windowsFolder = new Folder("windows");
AbstractFile *file = new File("TestComposite.java");
rootFolder->addChild(compositeFolder);
rootFolder->addChild(windowsFolder);
compositeFolder->addChild(file);
return 0;
}
5-2
计算三角形、矩形和正方形的面积并输出。(虚函数)
分数 10
作者 张德慧
单位 西安邮电大学
阅读下列说明和C++代码并填空。
【说明】以下程序的功能是计算三角形、矩形和正方形的面积并输出。
程序由4个类组成:类Triangle、Rectangle和Square分别表示三角形、矩形和正方形;抽象类Figure提供了一个纯虚拟函数getArea(),作为计算上述三种图形面积的通用接口。
【C++程序】
#include
#include
using namespace std;
class Figure {
public:
virtual double getArea() = 0; // 纯虚拟函数
};
class Rectangle :
public Figure
{
protected:
double height;
double width;
public:
Rectangle( ){};
Rectangle(double height, double width) {
this->height = height;
this->width = width;
}
double getArea ( ) {
return
height*width
;
}
};
class Square : public Rectangle{
public:
Square(double width){
this->width=height=width
;
}
};
class Triangle : public Figure {
double la;
double lb;
double lc;
public:
Triangle(double la, double lb, double lc) {
this->la = la; this->lb = lb; this->lc = lc;
}
double getArea() {
double s = (la+lb+lc)/2.0;
return sqrt(s*(s-la)*(s-lb)*(s-lc));
}
};
int main( ) {
Figure*
figures[3] = {
new Triangle(2,3,3), new Rectangle(5,8), new Square(5) };
for (int i = 0; i < 3; i++) {
cout <<
figures[i]->getArea()
<< endl;
}
}
函数题
6-1 从抽象类shape类派生出一个正五边形类(C++)
6-1 从抽象类shape类派生出一个正五边形类(C++)
分数 10
作者 张德慧
单位 西安邮电大学
从下列的抽象类shape类派生出一个正五边形(regular pentagon)类RPentagon,这个类将正五边形的边长作为私有成员,类中包含初始化这个值的构造函数。
class shape {// 抽象类
public:
virtual double getArea()=0;// 求面积
virtual double getPerimeter()=0; // 求周长
};
计算正五边形的面积公式为: S=a
2
×
25+10×
5
/4
正五边形类名:
RPentagon
裁判测试程序样例:
#include
#include
using namespace std;
class shape {// 抽象类
public:
virtual double getArea()=0;// 求面积
virtual double getPerimeter()=0; // 求周长
};
//你提交的代码将嵌入到这里
int main()
{
double s;
cin>>s;
RPentagon p(s);
cout<
class RPentagon:public shape{
public:
double a;
RPentagon(double s){
a=s;
}
double getArea(){
return a * a * sqrt(25 + 10 * sqrt(5)) / 4.0;
}
double getPerimeter(){
return 5*a;
}
};
6-2 从shape类派生出一个直角三角形类RTriangle
6-2 从shape类派生出一个直角三角形类RTriangle
分数 10
作者 张德慧
单位 西安邮电大学
从shape类派生出一个直角三角形类RTriangle类(regular triangle)。两条直角边长作为RTriangle类的私有成员,类中包含参数为直角边的构造方法。
class shape {// 抽象类
public:
virtual double getArea()=0;// 求面积
virtual double getPerimeter()=0; // 求周长
};
###直角三角形类名:RTriangle
直角三角形类的构造函数原型如下:
RTriangle(double a, double b);
其中 a 和 b 都是直角三角形的两条直角边。
裁判测试程序样例:
#include
#include
using namespace std;
class shape {// 抽象类
public:
virtual double getArea()=0;// 求面积
virtual double getPerimeter()=0; // 求周长
};
//你提交的代码将嵌入到这里
int main()
{
double a,b;
cin>>a>>b;
RTriangle t(a,b);
cout<
class RTriangle:public shape{
public:
double a;
double b;
RTriangle(double a1,double b1){
a=a1;
b=b1;
}
double getArea(){
return a * b / 2;
}
double getPerimeter(){
return a+b +sqrt(a*a+b*b);
}
};
6-3 求正9边形的面积和周长
6-3 求正9边形的面积和周长
分数 10
作者 张德慧
单位 西安邮电大学
求正9边形的面积和周长
在一个正n边形(Regular Polygon)中,所有边的边长都相等,且所有角的度数相同(即这个多边形是等边、等角的)。我们已经从下列抽象类shape实现了一个正n边形类RegularPolygon。其构造方法为:RegularPolygon(int n,double side); 其中n为边数,side为边长。
从键盘输入正9边形的边长s,请补充下列程序计算该正9边形的面积和周长。
class shape {// 抽象类
public:
virtual double getArea()=0;// 求面积
virtual double getPerimeter()=0; // 求周长
};
裁判测试程序样例:
#include
#include
using namespace std;
class shape {// 抽象类
public:
virtual double getArea()=0;// 求面积
virtual double getPerimeter()=0; // 求周长
};
//这里实现了正n边形类RegularPolygon,其构造函数为:RegularPolygon(int n,double side);
int main()
{
double s;
cin>>s;
return 0;
}
输入样例:
在这里给出一组输入。例如:
6.1828
输出样例:
在这里给出相应的输出。例如:
236.313
55.6452
RegularPolygon r(9,s);
cout<



