关于 c++ primer plus 中valarray类使用例程的一个记录
头文件:
#ifndef STUDENTC_H_ #define STUDENTC_H_ #include <iostream> #include <string> #include <valarray> class Student { private: typedef std::valarray<double> ArrayDb; std::string name; ArrayDb scores; //private method for scores 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, int n) :name(s), 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; //friend //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
函数实现:
#include "stdafx.h" #include "studentc.h" #include <iostream> using namespace std; //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 methods 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 //use string version of operator>>() 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; }
主函数
#include "stdafx.h" #include <iostream> #include "studentc.h" using namespace std; 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 << "\n Student 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 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; }
在主函数中被调用的赋值函数set(),完成了对Student类的赋值。自己一开始有疑惑的地方:
getline(cin, sa); getline() 函数被重新定义过,所以以类名做参数,输入姓名没问题, cin >> sa[i] 中, >> 没有重载,如何将分数输入类的valarray数组中的?
后来发现问题不是在 >> 上,而是在 [] 上, Student::operator[](int i) 函数的定义
double & Student::operator[](int i) { return scores[i]; //use valarray<double>::operator[]() } double Student::operator[](int i) const { return scores[i]; }
返回了scores 对象,所以 cin>> sa[i] 相当于cin >> sa.scores[i] .