继承与派生习题 15}
void employee::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; base_salary = Grades[grade]*(23 - days)/23; career_salary = base_salary/2;//普通员工业绩工资为基本工资的一半 salary = base_salary+career_salary; }
class manager:virtual public employee{//虚基类 protected: double prize;//固定奖金额 double factor;//业绩系数 public: manager(string=\"\int=0,int=0,double=0); void pay(); };
manager::manager(string nn,int id,int gr,double pr):employee(nn,id,gr){ prize = pr;//固定奖金额 factor = 0; }
void manager::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入业绩系数:\\n\"; cin>>factor; base_salary = Grades[grade]*(23 - days)/23; career_salary = prize*factor*(23 - days)/23; salary = base_salary + career_salary ; }
class technician:virtual public employee{ protected: double hours;//月工作时数 double perhour;//每小时附加酬金 double shfactor;//研究进度系数 public: technician(string=\"\int=0,int=0,double=0); void pay(); };
technician::technician(string nn,int id,int gr,double phr):employee(nn,id,gr){ hours = 0; perhour = phr;//每小时附加酬金 shfactor = 0;
16
}
void technician::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入研究进度系数:\\n\"; cin>>shfactor; hours=8*(23-days); base_salary = Grades[grade]*(23 - days)/23; career_salary = perhour*hours*shfactor*(23 - days)/23; salary= base_salary + career_salary ; }
class salesman:virtual public employee{ protected: double amount;//销售额 double slfactor;//提成比例 public: salesman(string=\"\int=0,int=0,double=0); void pay(); };
salesman::salesman(string nn,int id,int gr,double slfac):employee(nn,id,gr) { amount = 0; slfactor = slfac;//提成比例 }
void salesman::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入销售额:\\n\"; cin>>amount; base_salary = Grades[grade]*(23 - days)/23; career_salary = amount*slfactor; salary = base_salary + career_salary ; }
class developermanager:public manager,public technician { public: developermanager(string=\"\int id=0,int gr=0,double pr=0, double phr=0); void pay(); };
developermanager::developermanager(string nn,int id,int gr,double pr,double phr) :manager(nn,id,gr,pr),technician(nn,id,gr,phr),employee(nn,id,gr){} void developermanager::pay(){ int days;
继承与派生习题 17
cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入业绩系数:\\n\"; cin>>factor; cout<<\"请输入研究进度系数:\\n\"; cin>>shfactor; hours=8*(23-days); base_salary = Grades[grade]*(23 - days)/23;//基本工资 career_salary = perhour*hours*shfactor*(23 - days)/23;//技术人员奖金 career_salary += prize*factor*(23 - days)/23;//加经理业绩工资 career_salary /=2; salary = base_salary + career_salary ; }
class salesmanager:public manager,public salesman{ public: salesmanager(string=NULL,int=0,int=0,double pr=0, double slfac=0); void pay(); };
salesmanager::salesmanager(string nn,int id,int gr,double pr,double slfac) :manager(nn,id,gr,pr),salesman(nn,id,gr,slfac),employee(nn,id,gr){} void salesmanager::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入业绩系数:\\n\"; cin>>factor; cout<<\"请输入销售额:\\n\"; cin>>amount; base_salary = Grades[grade]*(23 - days)/23;//基本工资 career_salary = prize*factor*(23 - days)/23;//经理业绩工资 career_salary /=2; career_salary += amount*slfactor;//加销售业绩工资 salary = base_salary + career_salary ; }
int main(){ employee eml1(\"张伟\ manager mag1(\"姚婕\ technician tec1(\"王茜\ salesman sal1(\"朱明\ developermanager dem1(\"沈俊\ salesmanager sam1(\"况钟\ eml1.pay(); eml1.show(); mag1.pay();
18
mag1.show(); tec1.pay(); tec1.show(); sal1.pay(); sal1.show(); emlp=&dem1; emlp->pay(); emlp->show(); emlp=&sam1; emlp->pay(); emlp->show(); return 0; }
8.8 为上题添加拷贝构造函数,并测试是否正确。 解:
#include #include using namespace std;static int Grades[]={500,600,750,1000,1400,2000,2800,4000}; class employee{ protected: string name;//姓名 int ID;//职工号 int grade;//工资级别 double salary;//月 double base_salary;//基本月薪 double career_salary;//业绩工资 public: employee(string=\"\int=0,int=0); employee(employee &); //拷贝构造函数 virtual void pay(); //月薪计算函数 void show(); double getsalary(){return salary;} double getbase_salary(){return base_salary;} double getcareer_salary(){return career_salary;} };
employee::employee(string nn,int id,int gr){ name=nn; ID = id; grade = gr; salary=0; //月薪 base_salary=0; //基本月薪 career_salary=0; //业绩工资
继承与派生习题 19
}
employee::employee(employee &emp){ //拷贝构造函数 name=emp.name; ID=emp.ID; grade =emp.grade; salary=emp.salary; //月薪 base_salary=emp.base_salary; //基本月薪 career_salary=emp.career_salary;//业绩工资 }
void employee::show(){ cout<void employee::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; base_salary = Grades[grade]*(23 - days)/23; career_salary = base_salary/2; //普通员工业绩工资为基本工资的一半 salary = base_salary+career_salary; }class manager:virtual public employee{//虚基类 protected: double prize;//固定奖金额 double factor;//业绩系数 public: manager(string=\"\int=0,int=0,double=0); manager(manager&mag); //拷贝构造函数 void pay(); };
manager::manager(manager&mag):employee(mag){//按赋值兼容规则mag可为employee的实参 prize=mag.prize; factor=mag.factor; }
manager::manager(string nn,int id,int gr,double pr):employee(nn,id,gr){ prize = pr;//固定奖金额 factor = 0; }
void manager::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入业绩系数:\\n\"; cin>>factor; base_salary = Grades[grade]*(23 - days)/23;
20
career_salary = prize*factor*(23 - days)/23; salary = base_salary + career_salary ; }
class technician:virtual public employee{ protected: double hours;//月工作时数 double perhour;//每小时附加酬金 double shfactor;//研究进度系数 public: technician(string=\"\int=0,int=0,double=0); technician(technician &); //拷贝构造函数 void pay(); };
technician::technician(technician& tech):employee(tech){ //拷贝构造函数 hours=tech.hours;//月工作时数 perhour=tech.perhour;//每小时附加酬金 shfactor=tech.shfactor;//研究进度系数 }
technician::technician(string nn,int id,int gr,double phr):employee(nn,id,gr){ hours = 0; perhour = phr;//每小时附加酬金 shfactor = 0; }
void technician::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入研究进度系数:\\n\"; hours=8*(23 - days); cin>>shfactor; base_salary = Grades[grade]*(23 - days)/23; career_salary = perhour*hours*shfactor*(23 - days)/23; salary= base_salary + career_salary ; }
class salesman:virtual public employee{ protected: double amount;//销售额 double slfactor;//提成比例 public: salesman(string=\"\int=0,int=0,double=0); salesman(salesman &); //拷贝构造函数 void pay(); };
salesman::salesman(string nn,int id,int gr,double slfac):employee(nn,id,gr){
继承与派生习题 21
amount = 0; slfactor = slfac;//提成比例 }
salesman::salesman(salesman &sale):employee(sale){ //拷贝构造函数 amount=sale.amount;//销售额 slfactor=sale.slfactor;//提成比例 }
void salesman::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入销售额:\\n\"; cin>>amount; base_salary = Grades[grade]*(23 - days)/23; career_salary = amount*slfactor; salary = base_salary + career_salary ; }
class developermanager:public manager,public technician { public: developermanager(string=\"\int id=0,int gr=0,double pr=0, double phr=0); developermanager(developermanager &); //拷贝构造函数 void pay(); };
developermanager::developermanager(string nn,int id,int gr,double pr,double phr) :manager(nn,id,gr,pr),technician(nn,id,gr,phr),employee(nn,id,gr){} developermanager::developermanager(developermanager &deman) :manager(deman),technician(deman),employee(deman){} //拷贝构造函数 void developermanager::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入业绩系数:\\n\"; cin>>factor; cout<<\"请输入研究进度系数:\\n\"; cin>>shfactor; hours=8*(23 - days); base_salary = Grades[grade]*(23 - days)/23;//基本工资 career_salary = perhour*hours*shfactor*(23 - days)/23;//技术人员奖金 career_salary += prize*factor*(23 - days)/23;//加经理业绩工资 career_salary /=2; salary = base_salary + career_salary ; }
class salesmanager:public manager,public salesman{ public:
22
salesmanager(string=\"\int=0,int=0,double pr=0, double slfac=0); salesmanager(salesmanager &); //拷贝构造函数 void pay(); };
salesmanager::salesmanager(string nn,int id,int gr,double pr,double slfac) :manager(nn,id,gr,pr),salesman(nn,id,gr,slfac),employee(nn,id,gr){} salesmanager::salesmanager(salesmanager& salman) :manager(salman),salesman(salman),employee(salman){} //拷贝构造函数 void salesmanager::pay(){ int days; cout<<\"请输入请假天数:\\n\"; cin>>days; cout<<\"请输入业绩系数:\\n\"; cin>>factor; cout<<\"请输入销售额:\\n\"; cin>>amount; base_salary = Grades[grade]*(23 - days)/23;//基本工资 career_salary = prize*factor*(23 - days)/23;//经理业绩工资 career_salary /=2; career_salary += amount*slfactor;//加销售业绩工资 salary = base_salary + career_salary ; }
int main(){ employee eml1(\"张伟\ manager mag1(\"姚婕\ technician tec1(\"王茜\ salesman sal1(\"朱明\ developermanager dem1(\"沈俊\ salesmanager sam1(\"况钟\ eml1.pay(); eml1.show(); mag1.pay(); mag1.show(); tec1.pay(); tec1.show(); sal1.pay(); sal1.show(); emlp=&dem1; emlp->pay(); emlp->show(); emlp=&sam1; emlp->pay(); emlp->show(); cout<继承与派生习题 23}
employee eml0(eml1); manager mag0(mag1); technician tec0(tec1); salesman sal0(sal1);
developermanager dem0(dem1); salesmanager sam0(sam1);
cout<<\"输出拷贝结果:\"<show(); emlp=&sam0; emlp->show(); return 0;8.9 采用纯虚函数实现多态性来建立通用的双向链表派生类。参考【例8.10】和【例7.7】。 解: //ep8_9.h
#include using namespace std;//首先看结点组织,采用结点类加数据类 class Object{//数据类为抽象类 public: Object(){} virtual bool operator>(Object &)=0;//纯虚函数,参数必须为引用或指针 virtual bool operator!=(Object &)=0;//纯虚函数,参数必须为引用或指针 virtual void Print()=0;//纯虚函数 virtual ~Object(){} //析构函数可为虚函数,构造函数不行 };
class DblNode{ Object* info; //数据域用指针指向数据类对象 DblNode *llink,*rlink; //前驱(左链)、后继(右链)指针 public: DblNode(); //生成头结点的构造函数 ~DblNode(); void Linkinfo(Object* obj); friend class DblList; //以DblList为友元类,DblList可直接访问DblNode的私有函数,与结构一样方便,但更安全 };
DblNode::DblNode(){info=NULL;llink=rlink=NULL;}
24
DblNode::~DblNode(){ cout<<\"删除结点类\"<<'\'; delete info; //释放数据域 }
void DblNode::Linkinfo(Object * obj){info=obj;} //再定义双链表类,选择常用操作 class DblList{ DblNode *head,*current; public: DblList();//构造函数,生成头结点(空链表) ~DblList();//析构函数 void MakeEmpty();//清空链表,只余表头结点 void InsertFront(DblNode* p); //可用来向前生成链表,在表头插入一个结点 void InsertRear(DblNode* p); //可用来向后生成链表,在表尾添加一个结点 void InsertOrder(DblNode* p); //按升序生成链表 DblNode* CreatNode();//创建一个结点(孤立结点) DblNode* DeleteNode(DblNode* p); //删除指定结点 void PrintList();//打印链表的数据域 int Length();//计算链表长度 DblNode *Find(Object & obj);//搜索数据域与定值相同的结点,返回该结点的地址 //其它操作 };
DblList::DblList(){//建立表头结点 head=new DblNode(); head->rlink=head->llink=head; current=NULL; }
DblList::~DblList(){ MakeEmpty();//清空链表 cout<<\"删除头结点:\"; delete head; }
void DblList::MakeEmpty(){ DblNode *tempP; while(head->rlink!=head){ tempP=head->rlink; head->rlink=tempP->rlink;//把头结点后的第一个节点从链中脱离 tempP->rlink->llink=head;//处理左指针 delete tempP; //删除(释放)脱离下来的结点 } current=NULL; //current指针恢复 }
void DblList::InsertFront(DblNode *p){ p->llink=head;//注意次序
继承与派生习题 25
p->rlink=head->rlink; head->rlink->llink=p; head->rlink=p;//最后做 }
void DblList::InsertRear(DblNode *p){ p->rlink=head;//注意次序 p->llink=head->llink; head->llink->rlink=p; head->llink=p;//最后做 }
void DblList::InsertOrder(DblNode* p){ if(head==head->llink) { p->llink=head;//注意次序 p->rlink=head->rlink; head->rlink->llink=p; head->rlink=p;//最后做 } else{ current=head->rlink; while(current!=head){ if(*current->info>*p->info) break; //找第一个比插入结点大的结点 current=current->rlink; } p->rlink=current;//注意次序 p->llink=current->llink; current->llink->rlink=p; current->llink=p;//最后做 } }
DblNode* DblList::CreatNode(){//建立新节点 current=new DblNode(); return current; }
DblNode* DblList::DeleteNode(DblNode* p){ current=head->rlink; while(current!=head&¤t!=p) current=current->rlink; if(current==head) current=NULL; else{//结点摘下 p->llink->rlink=p->rlink; p->rlink->llink=p->llink; p->rlink=p->llink=NULL; } return current; }
26
DblNode* DblList::Find(Object & obj){//对抽象类只能用“引用” current=head->rlink; while(current!=head&&*current->info!=obj) current=current->rlink; if(current==head) current=NULL; return current;//搜索成功返回该结点地址,不成功返回NULL }
void DblList::PrintList(){ current=head->rlink; while(current!=head){ current->info->Print(); current=current->rlink; } cout<DblList::Length(){ int count=0; current=head->rlink; while(current!=head){ count++; current=current->rlink; } return count; }//ep8_9.cpp
#include \"ep8_9.h\" #include using namespace std;class StringObject:public Object{ string sptr; public: StringObject(); StringObject(string); ~StringObject(); bool StringObject::operator>(Object & obj);//虚函数 bool StringObject::operator!=(Object & obj);//虚函数 void Print(); };
StringObject::StringObject(){sptr=\"\";}
StringObject::StringObject(string s){sptr=s;}
StringObject::~StringObject(){cout<<\"删除字符串类\"<(Object & obj){//虚函数 StringObject & temp=(StringObject &)obj;//必须转换 return sptr>temp.sptr; }继承与派生习题 27
bool StringObject::operator!=(Object & obj){//虚函数 StringObject & temp=(StringObject &)obj;//必须转换 return sptr!=temp.sptr; }
void StringObject::Print(){cout<Linkinfo(p);//数据对象连接到结点 list1.InsertFront(P1);//向前生成list1 p=new StringObject(a[i]); P1=list2.CreatNode(); P1->Linkinfo(p); list2.InsertRear(P1);//向后生成list2 } list1.PrintList(); cout<<\"list1长度:\"<Linkinfo(p); list3.InsertOrder(P1);//升序创建list328
} list3.PrintList(); cout<<\"程序结束:\"<8.10 矩形法(rectangle)积分近似计算公式为:baf(x)dxx(y0y1yn1)
x[y02(y1yn1)yn] 2x[y0yn4(y1y3yn1)2(y2y4yn2)] 3梯形法(ladder)积分近似计算公式为:
baf(x)dx辛普生法(simpson)积分近似计算公式(n为偶数)为:
baf(x)dx被积函数用派生类引入,被积函数定义为纯虚函数。
基类(integer)成员数据包括:积分上下限b和a;分区数n;步长step=(b-a)/n,积分值result。定义积分函数integerate()为虚函数,它只显示提示信息。
派生的矩形法类(rectangle)重定义integerate(),采用矩形法作积分运算。 派生的梯形法类(ladder)和辛普生法(simpson)类似。 请编程,用三种方法对下列被积函数 (1) sin(x),下限为0.0和上限为π/2; (2) exp(x),下限为0.0和上限为1.0; (3) 4.0/(1+x*x),下限为0.0和上限为1.0。 进行定积分计算,并比较积分精度。
解:使用类参数传递被积函数,因类有数据域,也可以同时传递积分上下限,可由读者进行
修改。
#include #include using namespace std; class Base{ protected:double result,a,b,step;//Intevalue积分值,a积分下限,b积分上限 int n; public: virtual double fun(double x)=0;//被积函数声明为纯虚函数 virtual void Integerate(){ cout<<\"这里是积分函数\"<继承与派生习题 29} void Print(){ cout.precision(15); cout<<\"积分值=\"<class Rectangle:public Base{ public: void Integerate(){ int i; step=(b-a)/n; for(i=0;i<=n;i++) result+=fun(a+step*i); result*=step; } Rectangle(double ra,double rb,int nn):Base(ra,rb,nn){} };class Ladder:public Base{ public: void Integerate(){ int i; step=(b-a)/n; result=fun(a)+fun(b); for(i=1;iclass Simpson:public Base{ public: void Integerate(){ int i; step=(b-a)/n; result=fun(a)+fun(b); for(i=1;iclass sinR:public Rectangle{//矩形法和梯形法采用并列结构 public: sinR(double ra,double rb,int nn):Rectangle(ra,rb,nn){} double fun(double x){return sin(x);} };30
class sinL:public Ladder{ public: sinL(double ra,double rb,int nn):Ladder(ra,rb,nn){} double fun(double x){return sin(x);} };
class expR:public Rectangle{ public: expR(double ra,double rb,int nn):Rectangle(ra,rb,nn){} double fun(double x){return exp(x);} };
class expL:public Ladder{ public: expL(double ra,double rb,int nn):Ladder(ra,rb,nn){} double fun(double x){return exp(x);} };
class otherR:public Rectangle{ public: otherR(double ra,double rb,int nn):Rectangle(ra,rb,nn){} double fun(double x){return (4.0/(1+x*x));} };
class otherL:public Ladder{ public: otherL(double ra,double rb,int nn):Ladder(ra,rb,nn){} double fun(double x){return (4.0/(1+x*x));} };
class sinS:public Simpson{//辛普生法采用层次结构 public: sinS(double ra,double rb,int nn):Simpson(ra,rb,nn){} double fun(double x){return sin(x);} };
class expS:public sinS{ public: expS(double ra,double rb,int nn):sinS(ra,rb,nn){} double fun(double x){return exp(x);} };
class otherS:public expS{ public: otherS(double ra,double rb,int nn):expS(ra,rb,nn){} double fun(double x){return (4.0/(1+x*x));} };
int main(){ Base *bp; sinR sr(0.0,3./2.0,100); bp=&sr;
继承与派生习题 31
}
bp->Integerate();//动态,可以访问派生类定义的被积函数 bp->Print();
sinL sl(0.0,3./2.0,100); bp=&sl;
bp->Integerate();//动态,可以访问派生类定义的被积函数 bp->Print();
sinS ss(0.0,3./2.0,100); bp=&ss;
bp->Integerate();//动态,在层次中选 bp->Print();
expR er(0.0,1.0,100); bp=&er;
bp->Integerate();//动态,可以访问派生类定义的被积函数 bp->Print();
expL el(0.0,1.0,100); bp=⪙
bp->Integerate();//动态,可以访问派生类定义的被积函数 bp->Print();
expS es(0.0,1.0,100); bp=&es;
bp->Integerate();//动态,在层次中选 bp->Print();
otherR or(0.0,1.0,100); bp=∨
bp->Integerate();//动态,可以访问派生类定义的被积函数 bp->Print();
otherL ol(0.0,1.0,100);//增加到也达不到辛普生法的精度 bp=&ol;
bp->Integerate();//动态,可以访问派生类定义的被积函数 bp->Print();
otherS os(0.0,1.0,100); bp=&os;
bp->Integerate();//动态,在层次中选 bp->Print(); return 0;