}
};
voidmain()
{Base*pb;
Aobj1;
Bobj2;
pb=&obj1;
pb->getxy(10);
pb->fun();
pb=&obj2;
pb->getxy(100,20);
pb->fun();
}
8.2思考题
1.在C++中,使用类体系依靠什么机制实现程序运行时的多态?
2.如果一个基类的虚函数被声明为私有成员函数,会有语法错误吗?
可以在应用类体系时实现动态联编吗?
请你验证一下。
3.虚函数和纯虚函数的区别是什么?
4.一个非抽象类的派生类是否可以为抽象类?
利用例8-11进行验证,从Hex_type类派生一个Hex_format类,其中包含一个纯虚函数Show_format(),然后定义Hex_format的派生类实现Show_format()。
1.在C++中,使用类体系依靠什么机制实现程序运行时的多态?
【答案】
在C++中,基类指针可以指向派生类对象,以及基类中拥有虚函数,是支持多态性的前提。
程序通过用同一个基类指针访问不同派生类的虚函数重载版本实现程序运行时的多态。
C++的虚特性负责自动地在程序运行时把基类指针的关联类型转换成当前指向对象的派生类类型。
另外,抽象类机制提供了软件抽象和可扩展性的手段,实现运行时的多态性。
2.如果一个类的虚函数被声明为私有成员函数,会有语法错误吗?
当它作为基类时,可以在应用类体系时实现动态联编吗?
请你验证一下。
【答案】
没有语法错误。
但在应用类体系时无法实现动态编联和多态。
因为私有成员函数只在类内可见,在类外无法调用,无法在类外通过基类指针实现多态。
程序略。
3.虚函数和纯虚函数的区别是什么?
【答案】
虚函数定义时冠以关键字virtual,本身有实现代码,作用是引导基类指针根据指向对象调用类体系中不同重载版本函数。
纯虚函数是指在说明时代码“为0”的虚函数,即纯虚函数本身并没有实现代码,必须通过它的派生类定义实现版本。
4.一个非抽象类的派生类是否可以为抽象类?
利用例9-11进行验证,从Hex_type类派生一个Hex_format类,其中包含一个纯虚函数Show_format,然后定义Hex_format的派生类定义实现Show_format。
【答案】
一个非抽象类的派生类可以为抽象类,即在派生类中定义了纯虚函数。
程序略。
8.3 编程题
1.使用虚函数编写程序求球体和圆柱体的体积及表面积。
由于球体和圆柱体都可以看作由圆继承而来,所以可以定义圆类Circle作为基类。
在Circle类中定义一个数据成员radius和两个虚函数area()和volume()。
由Circle类派生Sphere类和Column类。
在派生类中对虚函数area()和volume()重新定义,分别求球体和圆柱体的体积及表面积。
答案8.3-1
#include
constdoublePI=3.14159265;
classcircle
{public:
circle(doubler){radius=r;}
virtualdoublearea(){return0.0;}
virtualdoublevolume(){return0.0;}
protected:
doubleradius;
};
classsphere:
publiccircle
{ public:
sphere(doubler):
circle(r){}
doublearea(){return4.0*PI*radius*radius;}
doublevolume()
{return4.0*PI*radius*radius*radius/3.0;}
};
classcolumn:
publiccircle
{ public:
column(doubler,doubleh):
circle(r){height=h;}
doublearea()
{return2.0*PI*radius*(height+radius);}
doublevolume()
{returnPI*radius*radius*height;}
private:
doubleheight;
};
voidmain()
{ circle*p;
spheresobj
(2);
p=&sobj;
cout<<"球体:
"< cout<<"体积="<volume()< cout<<"表面积="<area()< columncobj(3,5);
p=&cobj;
cout<<"圆柱体:
"< cout<<"体积="<volume()< cout<<"表面积="<area()<}
2.某学校对教师每月工资的计算规定如下:
固定工资+课时补贴。
教授的固定工资为5000元,每个课时补贴50元。
副教授的固定工资为3000元,每个课时补贴30元。
讲师的固定工资为2000元,每个课时补贴20元。
定义教师抽象类,派生不同职称的教师类,编写程序求若干个教师的月工资。
答案8.3-2
#include
#include
classteacher
{public:
teacher(chartname[],inttime)
{ strcpy(name,tname);
coursetime=time;
}
virtualintpay()=0;
virtualvoidprint()=0;
char*getname()
{returnname;}
intgetcoursetime()
{returncoursetime;}
protected:
charname[30];
intcoursetime;
};
classprofessor:
publicteacher
{public:
professor(charpname[],inttime):
teacher(pname,time){}
intpay()
{return5000+coursetime*50;}
voidprint()
{cout<<"教授:
"<};
classassociateprofessor:
publicteacher
{public:
associateprofessor(charpname[],inttime):
teacher(pname,time){}
intpay()
{return3000+coursetime*30;}
voidprint()
{cout<<"副教授:
"<};
classlecturer:
publicteacher
{public:
lecturer(charpname[],inttime):
teacher(pname,time){}
intpay()
{return2000+coursetime*20;}
voidprint()
{cout<<"讲师:
"<};
voidmain()
{professorpobj("李小平",32);
pobj.print();
cout<<'\t'<<"工资:
"< associateprofessorapobj("王芳芳",56);
apobj.print();
cout<<'\t'<<"工资:
"< lecturerlobj("何大建",72);
lobj.print();
cout<<'\t'<<"工资:
"<}
3.改写第7章习题7.4第3题,把Shape类定义为抽象类,提供共同操作界面的纯虚函数。
TwoDimShape类和ThreeDimShape类仍然抽象类,第3层具体类才能提供全部函数的实现。
在测试函数中,使用基类指针实现不同派生类对象的操作。
【答案】略
4.为第7章习题7.4中由第4,5,6小题定义的类体系定义一个抽象基类Counter,其中包含整型和实型数据成员,以及重载+,-,*,/,=,>>,<<等运算符的纯虚函数,并对原来的类体系做适当修改。
修改后的类库结构如图所示。
编写主函数,使用Counter类指针测试类体系的多态性。
【答案】略