1. 包含对象成员的类
接口和实现:使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚接口提供接口,但不提供实现)。获得接口是is-a关系的组成部分。而使用组合,类可以获得实现,但不能获得接口。不继承接口是has-a关系的组成部分。
#pragma once
// studentc.h
#ifndef STUDENTC_H_
#define STUDENTC_H_
#include <iostream>
#include <string>
#include <valarray>
class Student {
private:
std::string name;
std::valarray<double> scores;
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, int n) : name(s), scores(n) {}
Student(const std::string& s, const std::valarray<double>& 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);
};
#endif // !STUDENTC_H_
// studentc.cpp
#include "studentc.h"
using std::ostream;
using std::istream;
using std::endl;
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];
}
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;
}
// friends
istream& operator>>(istream& is, Student& stu) {
is >> stu.name;
return is;
}
// use string friend getline(ostream&, 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);
return os;
}
// use_stuc.cpp -- 14.3
#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;
int main() {
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