C++实验6报告

更新时间:2023-11-13 01:17:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

北京电子科技学院(BESTI)

课程: 面向对象程序设计

班级:

1022

姓名:

徐骏

学号:

102225

成绩:

D14

指导教师:

徐日 选修

实验日期:

2011.12.3

12:00~17:30

实验密级: 预习程度: 实验时间:

仪器组次: 实验名称:

必修/选修: 实验序号:

动态多态

实验目的与要求:

1. 使学生掌握掌握C++语言动态多态的基础编程;

2. 培养学生具有运用C++语言编程解决实际问题的能力,提高学生的计算机编程能力。 3. 引导和培养学生具有认真严谨的实验态度和用于实践的学习精神。

实验仪器: 名称 微机 型号 DELL Optiplex-755 数量 1

- 1 -

实验内容:

1. 类Emp、Manager、Seller、Piecer和Hourer 知识提示:

以虚函数为基础,实现用基类指针调用类结构中不同对象的成员函数。 题目:

编写一个工资管理程序,以雇员类为基类公有派生出经理类、

计件工类和小时工类。经理享有固定的底薪和业绩奖励;销售员的收入是一小部分的基本工资加上销售额的提成;计件工的收入完全取决于其生产的工件数量;小时工的收入以小时计算,再加上按时计算的加班费。运用基类指针显示输出各类对象的薪水值。

具体描述:

雇员类Emp作为基类,有数据成员salary(double型)表示薪水,成员函数set()为成员salary赋值(参数值为600),成员函数count()为salary赋值,成员函数get()获取成员salary的值,成员函数show()用于显示输出成员salary的值。

经理类Manager,新增成员函数count(),用于计算经理的薪水并对salary赋值,底薪8000,业绩奖励数额由用户输入(参考值为12000);新增成员函数show()用于显示成员salary的值。

计件工类Piecer,新增成员函数count(),用于计算计件工的薪水并对salary赋值,计件系数为40,生产产品件数由用户输入(参考值为80),新增成员函数show()用于显示输出成员salary的值。

小时工类Hourer,新增成员函数count(),用于计算小时工的薪

- 2 -

水并对salary赋值,150小时内的计时系数为10,150小时外的加班计时系数为20,工作时数由用户输入(参考值为170),新增成员函数show()用于显示输出成员salary的值。 要求:

1. 所有类定义时,数据成员为private属性,成员函数为public属性,各成员函数的参数请按需要自行设定。

2. 所有类都要求编写构造函数和析构函数,构造函数都为有参函数且具有默认参数值,构造函数完成数据成员的初始化。

3. 所有函数都要有明确的执行信息输出,例如类Emp的构造函数中应明确输出“执行类Emp的构造函数”。

4. 编写主函数main(),在其中编写程序,定义各类的对象,用基类指针指向它们分别操作,对各类对象的成员salary执行count()计算并赋值、执行show()对各类对象的成员salary的值输出显示。 5. 为便于理解题意,程序执行结果可参考下图。

编程设计思想:

因为基类有count()函数,而每一个派生类里面也有新增的count()函数,当基类的成员函数定义为虚函数后,当用基类指针指向这些派生类对象时,系统就会自动用派生类中的同名函数来代替基类中的虚函数。

程序源代码:

#include

- 3 -

class Emp//定义基类Emp { private:

double salary; public:

void set(double n)//执行类EMP的set函数 {

salary=n;

cout<<\执行类EMP的set函数,薪水赋值为<\ }

virtual void count(double n)//执行类EMP的count()函数 {

cout<<\执行类EMP的count()函数\ salary=n; }

double get()//执行类EMP的get()函数 {

cout<<\执行类EMP的get()函数,返回薪水值<\ return salary; }

virtual void show()//执行类EMP的show()函数 {

- 4 -

cout<<\执行类EMP的show()函数,输出薪水:\ }

Emp(double i=0)//执行类EMP的构造函数 {

cout<<\执行类EMP的构造函数\ salary=i; }

~Emp()//执行类EMP的析构函数 {

cout<<\执行类EMP的析构函数\ } };

class Manager:public Emp//定义Emp的派生类Manager { public:

void count(double n)//执行类Manager的count()函数 {

double i=n;

cout<<\执行类Manager的count()函数,经理业绩奖励额:\ Emp::set(n+8000); }

void show()//执行类Manager的show()函数

- 5 -

{

double a=get();

cout<<\执行类Manager的show()函数,输出薪水:\ }

Manager(double b):Emp(b)//执行类Manager的构造函数 {

cout<<\执行类Manager的构造函数\ }

~Manager()//执行类Manager的析构函数 {

cout<<\执行类Manager的析构函数\ } };

class Seller:public Emp//定义Emp的派生类Seller { public:

void count(double n)//执行类Seller的count()函数 {

double i=n;

cout<<\执行类Seller的count()函数,销售员的销售额:\ Emp::set(800+0.06*n); }

- 6 -

void show()//执行类Seller的show()函数 {

double a=get();

cout<<\执行类Seller的show()函数,输出薪水:\ }

Seller(double i):Emp(i)//执行类Seller的构造函数 {

cout<<\执行类Seller的构造函数\ }

~Seller()//执行类Seller的析构函数 {

cout<<\执行类Seller的析构函数\ } };

class Piecer:public Emp//定义Emp的派生类Piecer { public:

void count(double n)//执行类Piecer的count()函数 {

double i=n;

cout<<\执行类Piecer的count()函数,计件工生产产品件

- 7 -

数:\ Emp::set(40*n); }

void show()//执行类Piecer的show()函数 {

double a=get();

cout<<\执行类Piecer的show()函数,输出薪水:\ }

Piecer(double i):Emp(i)//执行类Piecer的构造函数 {

cout<<\执行类Piecer的构造函数\ }

~Piecer()//执行类Piecer的析构函数 {

cout<<\执行类Piecer的析构函数\ } };

class Hourer:public Emp//定义Emp的派生类Hourer { public:

void count(double n)//执行类Hourer的count()函数 {

double i=n;

- 8 -

cout<<\执行类Hourer的count()函数,小时工工时数:\ if(n<=150) {

Emp::set(10*n); }

if(n>150) {

Emp::set(1500+(n-150)*20); } }

void show()//执行类Hourer的show()函数 {

double a=get();

cout<<\执行类Hourer的show()函数,输出薪水:\ }

Hourer(double i):Emp( i)//执行类Hourer的构造函数 {

cout<<\执行类Hourer的构造函数\ }

~Hourer()//执行类Hourer的析构函数 {

cout<<\执行类Hourer的析构函数\ } };

- 9 -

void main(void) {

Emp *p,aa(0); p=&aa;

p->count(600); p->show(); Manager bb(0); p=&bb;

p->count(12000);

p->show(); Seller cc(0); p=&cc;

p->count(120000);

p->show(); Piecer dd(0); p=ⅆ p->count(80);

p->show(); Hourer ff(0); p=&ff;

- 10 -

p->count(170);

p->show(); }

结果如下:

执行类EMP的构造函数 执行类EMP的count()函数

执行类EMP的show()函数,输出薪水:600 执行类EMP的构造函数 执行类Manager的构造函数

执行类Manager的count()函数,经理业绩奖励额:12000 执行类EMP的set函数,薪水赋值为<20000> 执行类EMP的get()函数,返回薪水值<20000> 执行类Manager的show()函数,输出薪水:20000 执行类EMP的构造函数 执行类Seller的构造函数

执行类Seller的count()函数,销售员的销售额:120000 执行类EMP的set函数,薪水赋值为<8000> 执行类EMP的get()函数,返回薪水值<8000> 执行类Seller的show()函数,输出薪水:8000 执行类EMP的构造函数

- 11 -

执行类Piecer的构造函数

执行类Piecer的count()函数,计件工生产产品件数:80 执行类EMP的set函数,薪水赋值为<3200> 执行类EMP的get()函数,返回薪水值<3200> 执行类Piecer的show()函数,输出薪水:3200 执行类EMP的构造函数 执行类Hourer的构造函数

执行类Hourer的count()函数,小时工工时数:170 执行类EMP的set函数,薪水赋值为<1900> 执行类EMP的get()函数,返回薪水值<1900> 执行类Hourer的show()函数,输出薪水:1900 执行类Hourer的析构函数 执行类EMP的析构函数 执行类Piecer的析构函数 执行类EMP的析构函数 执行类Seller的析构函数 执行类EMP的析构函数 执行类Manager的析构函数 执行类EMP的析构函数 执行类EMP的析构函数 Press any key to continue

- 12 -

程序设计的亮点:

void count(double n)//执行类Manager的count()函数 {

double i=n;

cout<<\执行类Manager的count()函数,经理业绩奖励额:\ Emp::set(n+8000); }

- 13 -

类Manager的成员函数调用Emp的公有成员的成员函数set()来对salary进行赋值

2.类Person、Student、Graduate和GS(选作) 知识提示:

运用虚基类解决类的继承中的二义性问题。 题目:

设计类Person表示人员,以类Person为基类公有派生出类Student和类Graduate分别表示本科生和研究生,由类Student和类Graduate公有派生出类GS表示本硕连读生。编程实现对类GS对象所有数据成员值的修改和输出显示。 具体描述:

设计类Person表示人员,包含name(字符数组char [21])和age(int型)两个数据成员,分别表示人员的姓名和年龄,有成员函数getn()和geta()用于获取数据成员name和age的值,有成员函数p_set()用于修改name和age的值。

由类Person公有派生出类Student和类Graduate,分别用与表示本科生和研究生。

类Sstudent新增数据成员xh(字符数组 char[9]型)表示学好,新增成员函数s_set()用于修改数据成员xh,新增成员函数getx()用于获取数据成员xh的值

类Graduate新增数据成员id(字符数组 char[11])表示研究生的学号,新增成员函数g_set()用于修改数据成员id,新增成员函数getid()用于获取数据成员id的值。

由类Student和类Graduate公有派生出类GS表示本硕连读生。

- 14 -

要求:

1. 所有类定义时,数据成员为private属性,成员函数为public属性,各成员函数的参数请按需要自行设定。

2. 所有类都要求编写构造函数和析构函数,构造函数都为有参函数且具有默认参数值,构造函数完成数据成员的初始化。

3. 所有函数都要有明确的执行信息输出,例如类Person的构造函数中应明确输出“执行类Person的构造函数”。

4. 编写主函数main(),在其中编写程序以实现对GS对象的所有数据成员值的修改和输出显示。

5. 为便于理解,程序执行结果可参考下图

编程设计思想:

Person为基类,类Student和类Graduate都为类Person的基类公有派

生类。GS又由类Student和类Graduate公有派生出来。为了避免在派生类中产生二义性。

程序源代码:

//20102225 徐骏 #include #include

- 15 -

class Person//定义基类Person { private:

char name[21];//类Person的字符数组成员 int age; public:

void getn()//类Person的成员函数getn() {

cout<<\执行类Person的成员函数getn(),获取name=\ }

void geta()//类Person的成员函数geta() {

cout<<\执行类Person的成员函数geta(),获取age=\ }

void p_set(char a[],int n)//类Person的成员函数p_set() {

strcpy(name,a); age=n;

cout<<\执行类Person的成员函数p_set(),修改name=\修改age=\ }

- 16 -

Person(char a[]=\类Person的构造函数 {

cout<<\执行类Person的构造函数\ strcpy(name,a); age=n; }

~Person()//执行类Person的析构函数 {

cout<<\执行类Person的析构函数\ } };

class Student:virtual public Person//定义派生类Student { private: char xh[9]; public:

void s_set(char a[])//类Student的成员函数s_set() {

strcpy(xh,a);

- 17 -

cout<<\执行类Student的成员函数s_set(),修改xh=\ }

void getx()//类Student的成员函数getx() {

cout<<\执行类Student的成员函数getx(),获取xh=\ }

Student(char a[]=\

b[]=\执行类Student的构造函数 {

cout<<\执行类Student的构造函数\ strcpy(xh,b); }

~Student()//执行类Student的析构函数 {

cout<<\执行类Student的析构函数\ } };

class Graduate:virtual public Person//定义派生类Graduate { private:

- 18 -

char id[11]; public:

void g_set(char a[])//执行类Graduate的成员函数g_set() {

strcpy(id,a);

cout<<\执行类Graduate的成员函数g_set(),修改id=\ }

void getid()//执行类Graduate的成员函数getid() {

cout<<\执行类Graduate的成员函数getid(),获取id=\ }

Graduate(char a[]=\

c[]=\执行类Graduate的构造函数 {

cout<<\执行类Graduate的构造函数\ strcpy(id,c); }

~Graduate()//执行类Graduate的析构函数 {

cout<<\执行类Graduate的析构函数\ } };

- 19 -

class GS:public Student ,public Graduate//构造类GS {

public: //这个public特别重要,我就犯了这个错误,找了很久这个错误.

GS(char a[]=\

c[]=\执行类GS的构造函数 {

cout<<\执行类GS的构造函数\ }

~GS()//执行类GS的析构函数 {

cout<<\执行类GS的析构函数\ } };

void main(void)//定义主函数 {

GS ww(\

cout<<\下面输出初始化后类GS对象的数据成员值:\

- 20 -

ww.getn(); ww.geta(); ww.getx(); ww.getid();

cout<<\下面修改类GS对象的数据成员值:\ ww.p_set(\ ww.s_set(\ ww.g_set(\

cout<<\下面输出修改后类GS对象的数据成员值:\ ww.getn(); ww.geta(); ww.getx(); ww.getid(); }

结果如下:

执行类Person的构造函数 执行类Student的构造函数 执行类Graduate的构造函数 执行类GS的构造函数

下面输出初始化后类GS对象的数据成员值:

执行类Person的成员函数getn(),获取name=**GT**

- 21 -

执行类Person的成员函数geta(),获取age=3 执行类Student的成员函数getx(),获取xh=2008XXXX 执行类Graduate的成员函数getid(),获取id=08XXXXXXXX 下面修改类GS对象的数据成员值:

执行类Person的成员函数p_set(),修改name=xujun,修改age=20 执行类Student的成员函数s_set(),修改xh=20085X51 执行类Graduate的成员函数g_set(),修改id=0809XXXXXX 下面输出修改后类GS对象的数据成员值:

执行类Person的成员函数getn(),获取name=xujun 执行类Person的成员函数geta(),获取age=20 执行类Student的成员函数getx(),获取xh=20085X51 执行类Graduate的成员函数getid(),获取id=0809XXXXXX 执行类GS的析构函数 执行类Graduate的析构函数 执行类Student的析构函数 执行类Person的析构函数 Press any key to continue

- 22 -

程序设计的亮点: 这个貌似没亮点。

实验体会:

通过本次实验,我更加掌握了虚函数和虚基类的运用,我发现我在字符

数组这一块不熟悉,经过查阅资料才重新回顾了一下数组这块的知识。在做选作的时候,我的GS类中没有写pubulic导致程序一直出错,让我花了很多时间才发现了这个错误。以后做编程的实验,一定要认真仔细,按照逻辑一步一步的写,这样才能避免一些难以发现的错误。

- 23 -

思考题:

1.请例举或结合实验,说明虚函数的工作机制

答:当一个类的成员函数声明为虚函数后,就可以在该类的派生类中定义与其基类虚函数原型相同的函数。这时,当用基类指针指向这些派生类对象时,系统会自动派生类中的同名函数来代替基类的虚函数。例如实验中:count()函数在基类Emp中有,在其他派生类中也存在。定义count为虚函数后,定义的基类指针指向了派生类对象,系统会自动用派生类的count函数来代替基类的count虚函数。

2. 请举例或结合实验,说明虚基类的工作机制。

答:虚基类被一个派生类间接地多次继承,但派生类却只继承一份该基类的成员,这样就避免了派生类中访问这些成员时产生二义性。例如选作中:类Graduate和类Student都为Person的公有派生类,为了避免产生二义性,则定义派生时以虚基类的方式来派生。

- 24 -

- 25 -

- 26 -

本文来源:https://www.bwwdw.com/article/91qv.html

Top