关于 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 << ": 
";
    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 << "
 Student List : 
";
    for (i = 0; i < pupils; i++)
    {
        cout << endl << ada[i];
        cout << "average : " << ada[i].Average() << endl;
    }
    cout << "Done.
";

    return 0;
}

void set(Student & sa, int n)
{
    cout << "Please enter the student's name : ";
    getline(cin, sa);
    cout << "Please enter " << n << " quiz scores: 
";
    for (int i = 0; i < n; i++)
        cin >> sa[i];
    while (cin.get() != '
')
        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]    .

 
原文地址:https://www.cnblogs.com/heifengli/p/7478816.html