C++中的代码重用

①包含对象成员的类

1.介绍

学生可以表示成有姓名和一系列考试分数的人,我们基于此来开发Student类。对于姓名,我们可以采用string类来表示,对于考试分数,C++提供了一个根据string类设计表示数字数组的类,他就是valarray类。

2.valarray类介绍

valarray类是由头文件valarray支持的,是一个模板类,以便能够处理不同的数据类型。我们现在只需要知道模板类怎么应用,后边会讲到模板类的知识。

1.模板类声明对象

模板特性意味着声明对象时,必须指定具体的数据类型。valarray声明对象时,加上一对<>,并在其中包含所需的数据类型。

valarray<double> q_values;
valarray<int> weights;

2.类的构造函数

valarray<int> v1;   长度为0的int数组
valarray<double> v2(8);   长度为8的double空数组
valarray<int> v3(10,8);   长度为8的int数组,每个数字被设置为10
double gpa[5] ={3.1,3.2,4.1,3.5,3.8};
valarray<double> v4(gpa,4);   长度为为gpa前4个元素的数组
valarray<int> v1 = {1,2,3,4,5};  初始化列表进行初始化

3.类的一些方法

operator[]();    访问数组元素
size();
sum();
max();
min();

还有很多其他方法,16章介绍 

3.示例

①Student类设计

至此,我们已经确定了Student类的设计计划,设计方法有两种:

1.从string类 和valarray类派生出Student类,这里并不合适,因为学生与这两个类不是is-a的关系,这里的关系应该是has-a;学生有姓名和分数,而不是学生是姓名和分数。通常,用于建立has-a关系的C++技术是组合(包含),即创建一个包含其他类对象的类。

使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚函数提供接口,但不提供实现)。而使用组合,类可以获得实现(方法都是在的,能不能用就不知道了),但不能获得接口(不能直接使用使用被包含的类的方法,除非通过成员函数来使用,然后在类外边通过该类的公有接口来间接使用方法)。

②Student类示例

#ifndef STUDENT_H_
#define STUDENT_H_
#include<string>
#include<valarray>
using std::string;
using std::valarray;

class Student
{
private:
	typedef valarray<double> ArrayDb;   //简化表示,student类外不能使用
	string name;
	ArrayDb scores;
	std::ostream& arr_out(std::ostream& os) const;     //valarray不能通过<<来输出,没有这样的实现,所以定义私有方法来处理这种任务
public:
	Student():name("Null Student"),scores(){};
	explicit Student(const string & na):name(na),scores(){};
	explicit Student(int n):name("Null Student"),scores(n){};
	Student(const string& na,int n) :name(na), scores(n) {};
	Student(const char * str, const double *pd,int n) :name(str), scores(pd,n) {};
	double Average()const;
	const string& Name()const;
	const double& operator[](int i)const;
	double& operator[](int i);
	~Student();

	friend std::istream& operator>>(std::istream& is, Student& stu);
	friend std::ostream& operator<<(std::ostream& os, Student& stu);
	friend std::istream& getline(std::istream& is, Student& stu);   //不是运算符重载,是重新定义函数,函数的重载
};


#endif
#include<iostream>
#include"student.h"

double Student::Average()const
{
	if (scores.size() > 0)
		return scores.sum() / scores.size();
	else
		return 0;
}
const string& Student::Name()const
{
	return name;
}
const double& Student::operator[](int i) const
{
	return scores[i];
}
double& Student::operator[](int i)
{
	return scores[i];
}
Student::~Student(){};

//
std::istream& operator>>(std::istream& is, Student& stu)
{
	is >> stu.name;
	return is;
 }
std::ostream& operator<<(std::ostream& os, Student& stu)
{
	os << "name:" << stu.name << std::endl;
	stu.arr_out(os);
	return os;
 }
std::istream& getline(std::istream& is, Student& stu)
{
	getline(is, stu.name);
	return is;
 }
std::ostream& Student::arr_out(std::ostream& os) const
{
	int i;
	int lim = scores.size();
	if (lim > 0)
	{
		for (i = 0; i < lim; i++)
		{
			os << scores[i] << " ";
			if (i % 5 == 4)
				os << std::endl;
		}
		if (i % 5 != 0)
			os << std::endl;
	}
	else
		os << "empty array ";
	return os;
}

 

#include<iostream>
#include"student.h"
using std::cin;
using std::cout;
using std::endl;

void set(Student& sa, int n);
const int pupils = 3;
const int quizzes = 5;
int main()
{
	Student ada[pupils] =
	{
		Student(quizzes),Student(quizzes),Student(quizzes)
	};
	int i;
	for (int i = 0; i < pupils; ++i)
		set(ada[i], quizzes);
	cout << "\nStudent List:\n";
	for (i = 0; i < pupils; i++)
	{
		cout << endl << ada[i];
		cout << "average:" << ada[i].Average() << endl;
	}
	cout << "Done.\n";
	return 0;
}
void set(Student& sa, int n)
{
	cout << "Please enter the students' name:";
	getline(cin, sa);
	cout << "Please enter " << n << " quiz scores:\n";
	for (int i = 0; i < n; i++)
		cin >> sa[i];
	while (cin.get() != '\n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值