继承和动态绑定

对研究生和本科生进行统计,并计算成绩,使用一个基本类表示本科生的相关信息,研究生继承本科生公共接口,在通过一个接口类进行相应操作,从而封装学生信息

两个类头文件

#ifndef _grad_h
#define _grad_h

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>

#include"grade_deal.h"

class Grad{
	friend class Student;
	 std::string n;
protected:
	double midterm,final;
	 std::vector<double> homework;
	 std::istream& read_common(std::istream&);
	virtual Grad* clone() const {return new Grad(*this);}
public:
	Grad():midterm(0),final(0) { }
	Grad( std::istream& is) {read(is); }
	virtual ~Grad() { }
	virtual  std::istream& read( std::istream&);
	virtual double grade()const {return ::grade(midterm,final,homework); }
	 std::string name() const {return n;}
};

class Post_Grad:public Grad{
	double thesis;
protected:
	Post_Grad* clone() const {return new Post_Grad(*this);}
public:
	Post_Grad():thesis(0) { }
	Post_Grad( std::istream& is) {read(is); }
	 std::istream& read( std::istream&);
	double grade()const {return  std::min(thesis,Grad::grade());}
	
};

#endif
实现

#include"grad.h"

using namespace std;

 istream& read_hw( istream& is, vector<double>& hw){
	hw.clear();
	if(is){
		double x;
		while(is>>x)
		  hw.push_back(x);
		is.clear();
	}
	return is;
}

 istream& Grad::read_common( istream& is){
	is>>n>>midterm>>final;
	return is;
}

 istream& Grad::read( istream& is){
	read_common(is);
	::read_hw(is,homework);
	return is;
}

 istream& Post_Grad::read( istream& is){
	read_common(is);
	is>>thesis;
	::read_hw(is,homework);
	return is;
}
成绩处理头文件

#ifndef _grade_deal_h
#define _grade_deal_h

#include<stdexcept>
#include<vector>

double grade(double,double,const std::vector<double>&);
double grade(double,double,double);

#endif
成绩实现源文件

#include"grade_deal.h"

#include<algorithm>

using namespace std;

template <class T> T median( vector<T> hw){
	typename  vector<T>::size_type sz=hw.size();
	if(sz==0)
	  throw  domain_error("vector size false");
	sort(hw.begin(),hw.end());
	typename  vector<T>::size_type mid=hw.size()/2;
	return sz%2==0? (hw[mid-1]+hw[mid])/2 : hw[mid];
}

double grade(double midterm,double final,const  vector<double>& hw){
	if(hw.size()==0)
	  throw domain_error("vector size false");
	return grade(midterm,final,median(hw));
}

double grade(double midterm,double final,double hw){
	return midterm*0.2+final*0.4+0.4*hw;
}
学生成绩处理接口类头文件

#ifndef _student_h
#define _student_h

#include"grad.h"

class Student{
	Grad* cp;
public:
	Student(): cp(0) { }
	Student( std::istream& is) {read(is);}
	Student(const Student&);
	Student& operator=(const Student&);
	~Student() {delete cp;}
	std::string name() const{
	  if(cp)
	    return cp->name();
	  else throw  std::domain_error("uninitial student");
	}
	
	double grade()const {
	  if(cp)
	    return cp->grade();
	  else throw  std::domain_error("uninitial student");
	}
	static bool compare(const Student& s1,const Student& s2){
		return s1.name() < s2.name();
	}
     std::istream& read( std::istream& is);
};

#endif
实现

#include"student.h"

using namespace std;

istream& Student::read( istream& is){
	delete cp;
	char c;
	is>>c;
	if(c=='G')
	  cp=new Grad(is);
	else if(c=='P')
	  cp=new Post_Grad(is);
	return is;
}
Student::Student(const Student& stu){
	if(stu.cp)
		cp=stu.cp->clone();	
}

Student& Student::operator=(const Student& stu){
	if(&stu != this){
	  if(stu.cp){
		delete cp;
		cp=stu.cp->clone();
	  }else cp=0;
	}
    return *this;
	
}

测试例程

#include"student.h"

#include<ios>
#include<iomanip>


using namespace std;

int main(){
	vector<Student> students;
	Student record;
	string::size_type maxlen=0;
	while(record.read(cin)){
		maxlen=max(maxlen,record.name().size());
		students.push_back(record);
	}
	sort(students.begin(),students.end(),Student::compare);
	for(vector<Student>::size_type i=0;i!=students.size();i++){
		cout<<students[i].name()<<string(maxlen+1-students[i].name().size(),' ');
		try{
			double final_grade=students[i].grade();
			streamsize prec=cout.precision();
			cout<<setprecision(3)<<final_grade<<setprecision(prec)<<endl;
		}catch(domain_error e){
			cout<<e.what()<<endl;
		}
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值