C网络作业答案.docx
《C网络作业答案.docx》由会员分享,可在线阅读,更多相关《C网络作业答案.docx(16页珍藏版)》请在冰豆网上搜索。
C网络作业答案
作业4
一、选择题
1.下列关于动态联编的描述中,错误的是_________。
D
A)动态联编是以虚函数为基础的
B)动态联编是在运行时确定所调用的函数代码的
C)动态联编调用函数操作是指向对象的指针或对象引用
D)动态联编是在编译时确定操作函数的
注:
先期联编也称静态联编,迟后联编也称动态联编。
注释:
动态联编一直要到程序运行时才能确定调用哪个函数。
虚函数是实现动态联编的必要条件之一。
没有虚函数一定不能实现动态联编,但
有虚函数存在时,必须同时满足下列条件,才能够实现动态联编:
●类之间满足子类型关系;
●调用虚函数操作的是指向对象的指针或者对象引用:
或者是由成员函数调用
虚函数。
2关于虚函数的描述中,正确的是________。
D
A)虚函数是一个静态成员函数
B)虚函数是一个非成员函数
C)虚函数既可以在函数说明时定义,也可以在函数实现时定义
D)派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型
注释:
虚函数是非静态的成员函数。
它不能是友元函数,但可以在另一个类中被声明
为友元函数。
虚函数声明只能出现在类定义的函数原型声明中,而不能在成员函数的函数体实
现的时候。
派生类的虚函数与基类中对应的虚函数必须满足下列条件,否则派生类中的虚函
数将丢失其虚特性,在调用时进行静态联编:
●派生类中的虚函数与基类中的虚函数具有相同的名称:
●派生类中的虚函数与基类中的虚函数具有相同的参数个数和相同的对应参数
类型:
●派生类中的虚函数与基类中的虚函数的返回值或者相同,或者都返回指针或
引用,并且派生类虚函数所返回的指针或引用的基类型是基类中的虚函数所
返回的指针或引用的基类型的子类型。
3在下面四个选项中,________是用来声明虚函数的。
A
A)virtualB)publicC)usingD)false
注释:
说明虚函数的一般格式如下:
virtua1<函数返回类型><函数名>(<参数表>)
4对虚函数的调用________。
D
A)一定使用动态联编B)必须使用动态联编
C)一定使用静态联编D)不一定使用动态联编
注释:
参见第1题的注释。
5实现运行时的多态性要使用___________。
D
A)重载函数B)构造函数C)析构函数D)虚函数
注释:
参见第1题的注释。
6要实现动态联编,必须通过____调用虚函数。
A
A)对象指针B)成员名限定C)对象名D)派生类名
注释:
参见第1题的注释。
7在派生类中重新定义虚函数时,除了_____方面,其他方面都必须与基类中相应的
虚函数保持一致。
D
A)参数个数B)参数类型C)函数名称D)函数体
注释:
参见第2题的注释。
8下面关于构造函数和析构函数的描述,错误的是__。
D
A)析构函数中调用虚函数采用静态联编
B)对虚析构函数的调用可以采用动态联编
C)当基类的析构函数是虚函数时,其派生类的析构函数也一定是虚函数
D)构造函数可以声明为虚函数
注释:
构造函数不能声明为虚函数,但析构函数可以声明为虚函数。
当基类的析构函
数声明为虚函数时,无论派生类是否使用virtual关键字说明,派生类的析构函数一定
是虚函数,对缺省析构函数亦然。
而且,如果满足动态联编的其他条件,对虚析构函
数的调用将采用动态联编。
构造函数不能声明为虚函数,但在构造函数中可以调用虚函数。
在构造函数或析
构函数中调用虚函数,将采用静态联编。
9关于纯虚函数和抽象类的描述中,错误的是__。
C
A)纯虚函数是一种特殊的虚函数,它没有具体的实现
B)抽象类是指具有纯虚函数的类
C)一个基类中说明有纯虚函数,该基类的派生类一定不再是抽象类
D)抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出
注释:
带有纯虚函数的类称为抽象类。
抽象类中的纯虚函数的实现由派生类给出:
但派生类仍可不给出纯虚函数的定义,继续作为抽象类存在。
10下列描述中,____是抽象类的特性。
D
A)可以说明虚函数B)可以进行构造函数重载
C)可以定义友元函数D)不能说明其对象
注释:
抽象类区别于其他类的最根本的特征是不能定义对象。
11_______是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生
类都必须定义自己的版本。
C
A)虚析构函数B)虚构造函数C)纯虚函数D)静态成员函数
12如果一个类至少有一个纯虚函数,那么就称该类为__。
A
A)抽象类B)虚基类C)派生类D)以上都不对
13以下___成员函数表示纯虚函数。
C
A)virtualintvf(int);B)voidvf(int)=0;
C)virtualvoidvf()=0;D)virtualvoidvf(int)()
注释:
纯虚函数的声明格式如下:
virtual<函数返回类型><函数名>(<参数表>)=0;
注意纯虚函数与虚函数体为空的区别。
纯虚函数根本就没有函数体,而空的虚
函数的函数体为空:
前者所在的类是抽象类,不能直接进行实例化,而后者所在的
类是可以实例化的:
14下面的描述中,正确的是_____。
A
A)virtual可以用来声明虚函数
B)含有纯虚函数的类是不可以用来创建对象的,因为它是虚基类
C)即使基类的构造函数没有参数,派生类也必须建立构造函数
D)静态数据成员可以通过成员初始化列表来初始化
注释:
virtual关键字既可以用来声明虚基类,也可以用来声明虚函数。
含有纯虚函数的类是抽象类,它不能用来定义对象。
静态数据成员的初始化必须在类体外进行。
如果所有的基类和子对象构造函数都不需要参数,派生类也不需要参数时,派
生类构造函数可以不定义。
15在下面程序中,A、B、C、D四句编译时不会出现错误的是__。
A
#include<>
classBase
{
public:
Base(){}
Base(intc):
count(c){}
virtualvoidprint()const=0;
private:
intcount;
};
classDerived:
publicBase
{
public:
Derived():
Base(0){}
Derived(intc):
Base(c){}
voidprint()const{cout<<"Derived"<};
voidmain()
{
Derivedd(10);
Base*pb;
pb=&d;Derive2'sPrint()called.
根据结果将程序补充完整。
#include<>
classBase
{
public:
Base(inti){b=i;}
___①virtualvoidPrint()=0;___
protected:
intb;
};
classDerivel:
publicBase
{
public:
___②Derive1(inti):
Base(i){}___
voidPrint()
{
cout<<”Derive1’sPrint()called.”<}
};
classDerive2:
publicBase
{
_③public:
Derive1(inti):
Base(i){}
voidPrint(){cout<<”Derive2’sPrint()called.“<};
voidfun(_④Base*obj__)
{
obj->Print();
}
voidmain()
{
_⑤Derive1*d1=newDerive1
(1);_
Derive2*d2=newDerive2
(2);
fun(dl);
fun(d2);
}
注释:
派生类Derived1和Derived2从基类Base公有继承,它们是Base的子类型。
主程序中两次调用fun函数,该函数通过指针对象obj调用了Print函数,得到
了不同的输出结果。
而同样的消息被不同类型的对象接收时导致完全不同的行为,
恰好体现了面向对象的多态特性。
根据运行时的多态必须满足的条件,Print函数一
定是一个虚函数,并且在所有类中都必须进行定义。
由于Base类中的Print函数除
了提供一个公共的接口外,没有其他的作用,所以最好定义为纯虚函数。
12将下列程序补充完整。
#include<>
classconvert
{
public:
convert(doublei){vail=i;}
_①virtualvoidcompute()=0;___
protected:
doubleval1;
doubleval2;
};
<}
};
<}
};
voidfun(__④convert&f_)
{
();
}
voidmain()
{
l_to_glgobj(4);
f_to_cfcobj(70);
fun(lgobj);
fun(fcobj);
}
13根据不同的输出结果,在函数Tone中填入正确的语句。
#include<>
classInstrument
{
public:
virtualvoidPrint()const{cout<<"Instrument:
:
Print"<};
classPiano:
publicInstrument
{
public:
voidPrint()const{cout<<"Piano:
:
Print"<};
classGuitar:
publicInstrument
{
public:
voidPrint()const{cout<<"Guitar:
:
Print"<};
voidTone(_____①_____)
{
___②_____
}
voidmain()
{
Guitarg;
Tone(g);
Pianop;
Tone(p);
}
(1)输出结果为:
Instrument:
:
Print
Instmment:
:
Print
(2)输出结果为:
Guitar:
:
Print
Piano:
:
Print
(1)①Instrumentobj②()
(2)①Instrument&obj②()
参考第3题,第一次的输出是由静态联编产生的,第二次的输出是由动态态联编产生的。
14下列程序的运行结果如下:
Base'scons.
Derived'scons.
Derived'sdes.
Base'sdes.
根据结果将程序补充完整。
#include<>
classBase
{
public:
Base(){cout<<"Base'scons."<_①virtual~Base()_{cout<<"Base'sdes."<};
classDerived:
publicBase
{
public:
Derived(){cout<<"Derived'scons."<~Derived(){cout<<"Derived'sdes."<};
voidmain()
{
Base*ptr=_____②newDerived______
deleteptr;
}
三、编程
1.在作业1编程1的Point类中完成赋值运算符=、插入运算符<<、比较运算符==、!
=和加法运算符+、-的重载。
#include<>
#include<>
classPoint
{public:
Point(floatx=0,floaty=0,floatz=0):
x_(x),y_(y),z_(z){}
Point(constPoint&p):
x_,y_,z_{}
3A6A9C11C12A13C14A15A16C2’“<④Base*obj ⑤Derive1*d1=newDerive1
(1);_
Derive2*d2=newDerive2
(2);
11①virtualvoidcompute()=0; ②l_to_g(doublei):
convert(i){}
③public:
f_to_c(doublei):
convert(i){}
voidcompute()
{
val2=(val1-32)*5/9;
cout<}
④convert&f
}
13
(1)①Instrumentobj②()
(2)①Instrument&obj②()
14 ①virtual~Base() ②newDerived
三、编程
1,
#include<>
#include<>
classPoint
{public:
Point(floatx=0,floaty=0,floatz=0):
x_(x),y_(y),z_(z){}
Point(constPoint&p):
x_,y_,z_{}
voidnegate(){x_*=-1;y_*=-1;z_*=-1;}
doublenorm(){returnsqrt(x_*x_+y_*y_+z_*z_);}
voidprint()
{cout<<'('<}
Point&operator=(constPoint&point);
boolPoint:
:
operator==(constPoint&point)const
{returnx_==&&y_==&&z_==;
}
boolPoint:
:
operator!
=(constPoint&point)const
{returnx_!
=||y_!
=||z_!
=;
}
friendPointoperator+(constPoint&p1,constPoint&p2);
friendPointoperator-(constPoint&p1,constPoint&p2);
friendostream&operator<<(ostream&ostr,constPoint&point);
private:
floatx_,y_,z_;
};
Pointoperator+(constPoint&p1,constPoint&p2)
{returnPoint+,+,+;
}
Pointoperator-(constPoint&p1,constPoint&p2)
{returnPoint&operator<<(ostream&ostr,constPoint&point)
{returnostr<<"("<<<<","<<<<","<<<<")";
}
Point&Point:
:
operator=(constPoint&point)
{x_=;
y_=;
z_=;
return*this;
}
voidmain()
{Pointp(12,-3,4),q(14,5,12),r1,r2;
r1=p+q;
cout<r2=p-q+r1;
cout<if(r1==r2)cout<<"r1==r2"<elsecout<<"r1!
=r2"<}
2,
#include<>
#include<>
classPoint
{public:
Point(intx=0,inty=0,intz=0):
x_(x),y_(y),z_(z){}
Point(constPoint&p):
x_,y_,z_{}
Point&operator++()
{x_++;y_++;z_++;
return*this;
}
Pointoperator++(int)
{Pointtemp(*this);
x_++;y_++;z_++;
returntemp;
}
Point&operator--()
{x_--;y_--;z_--;
return*this;
}
Pointoperator--(int)
{Pointtemp(*this);
x_--;y_--;z_--;
returntemp;
}
voidprint()
{cout<<'('<}
private:
intx_,y_,z_;
};
voidmain()
{Pointp(12,-3,4);
cout<<"p=";
();
Pointq(p++);
cout<<"q=";
();
cout<<"p=";
();
++(++p);
cout<<"p=";
();
p--;
cout<<"p=";
();
}
3,
#include<>
classShape
{public:
//Shape(){}
//~Shape(){}
virtualfloatGetArea(){return-1;}
};
classCircle:
publicShape
{
public:
Circle(floatradius):
itsRadius(radius){}
//~Circle(){}
floatGetArea(){return*itsRadius*itsRadius;}
private:
floatitsRadius;
};
classRectangle:
publicShape
{
public:
Rectangle(floatlen,floatwidth):
itsLength(len),itsWidth(width){};
//~Rectangle(){};
floatGetArea(){returnitsLength*itsWidth;}
floatGetLength(){returnitsLength;}
floatGetWidth(){returnitsWidth;}
private:
floatitsWidth;
floatitsLength;
};
classSquare:
publicRectangle
{
public:
Square(floatlen);
//~Square(){}
};
Square:
:
Square(floatlen):
Rectangle(len,len)
{}
voidmain()
{
Shape*sp;
sp=newCircle(5);
cout<<"TheareaoftheCircleis"<GetArea()<deletesp;
sp=newRectangle(4,6);
cout<<"TheareaoftheRectangleis"<GetArea()<deletesp;
sp=newSquare(5);
cout<<"TheareaoftheSquareis"<GetArea()<deletesp;
}
4,
#include<>
classShape
{public:
//Shape(){}
//~Shape(){}
virtualfloatGetArea()=0;
virtualfloatGetPerim()=0;
};
classCircle:
publicShape
{
public:
Circle(floatradius):
itsRadius(radius){}
//~Circle(){}
floatGetArea(){return*itsRadius*itsRadius;}
floatGetPerim(){return*itsRadius;}
private:
floatitsRadius;
};
classRectangle:
publicShape
{
public:
Rectangle(floatlen,floatwidth):
itsLength(len),itsWidth(width){};
//~Rectangle(){};
virtualfloatGetArea(){returnitsLength*itsWidth;}
floatGetPerim(){return2*(itsLength+itsWidth);}
private:
floatGetLength(){returnitsLength;}
floatGetWidth(){returnitsWidth;}
private:
floatitsWidth;
floatitsLength;
};
voidmain()
{
Shape*sp;
sp=newCircle(5);
cout<<"TheareaoftheCircleis"<GetArea()<cout<<"ThePerimeteroftheCircleis"<GetPerim()<deletesp;
sp=newRectangle(4,6);