本小结主要讲解一种代码重用的形式 可以叫做包含、组合、或者层次化。本质上都是使用这样的类成员:本身就是另一个类的对象。包含、私有继承和保护继承用于实现has-a的关系,而共有继承是实现了is-a关系。使用组合,类可以获得实现,但不能获得接口。例如,你有一个string name,就可以使用string 所带给你的能力。
首先介绍包含对象成员的类。学生类,它有两个成员:名字,string name 和 用于表示分数的数组valarray<double> sores;valarray是定义在头文件valarray中的,这个类用于处理数值,例如可以求和、求最大值,最小值等这是个模板类。
valarray<double> sores: 一个double数组
valarray<int> sores 一个int 数组
下面的程序实现了类student 和一些操作。
student.h
#pragma once
#include <iostream>
#include <string>
#include <valarray>
class Student
{
private:
typedef std::valarray <double> ArrayDb;
std::string name;// contained object 被包含的对象
ArrayDb scores; // contained object 被包含的对象
//private method for socres output
std::ostream& arr_out(std::ostream& os) const;
public:
Student():name("Null Student"), scores() {}
explicit Student(const std::string & s):name(s),scores(){}
explicit Student(int n) :name("Nully"), scores(n) {}
Student(const std::string &s,const ArrayDb & a):name(s),scores(a){}
Student(const char * str,const double * pd,int n):name(str),scores(pd,n){}
~Student(){}
double Average() const;
const std::string& Name()const;
double& operator [](int i);
double operator[](int i) const ;
//friends
//input
friend std::istream& operator>>(std::istream& is, Student& stu);//1 word
friend std::istream& getline(std::istream& is, Student& stu);// 1 line
//output
friend std::ostream& operator<<(std::ostream& os, const Student& stu);
};
studentc.cpp
#include "studentc.h"
using std::ostream;
using std::endl;
using std::istream;
using std::string;
//public methods
double Student::Average()const
{
if (scores.size() > 0)
return scores.sum() / scores.size();
else
return 0;
}
const string& Student::Name()const
{
return name;
}
double& Student::operator[](int i)
{
return scores[i];//use valarray<double>::operator []{}
}
double Student::operator[](int i)const
{
return scores[i];
}
//private method
ostream& Student::arr_out(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 << endl;
}
if (i % 5 != 0)
os << endl;
}
else
os << "empty array ";
return os;
}
//frieds
//use string version of operator >>()
istream& operator >>(istream& is, Student& stu)
{
is >> stu.name;
return is;
}
//use string friend getline(istream &,const string &)
istream& getline(istream& is, Student& stu)
{
getline(is,stu.name);
return is;
}
//use string version of operator <<()
ostream& operator<<(ostream& os, const Student& stu)
{
os << "Scores for " << stu.name << ":\n";
stu.arr_out(os);//use private method for scores
return os;
}
主函数在这里:use_stuc.cpp
// Chapter14.1Composition_Studentc.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "studentc.h"
using std::cin;
using std::cout;
using std::endl;
void set(Student & sa,int n);
const int pupils = 3;//三个学生对象
const int quizzes = 5;//每个学生对象保存5个考试成绩
int main()
{
// std::cout << "Hello World!\n";
Student ada[pupils] = { Student(quizzes),Student(quizzes), Student(quizzes) };
int i;
for (i = 0; i < pupils; ++i)
set(ada[i],quizzes);
cout << "\nStudent List: \n";
for (i = 0; i < pupils; ++i)
{
cout << ada[i].Name() << endl;
}
cout << "\nResults:";
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 student's 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')
{
continue;
}
}