我正在关注 Accelerated C++ 这本书,但我对他们提供的源代码感到困惑。我的困惑涉及函数
double grade(double midterm, double final, const vector<double>& hw)
和double median(vector<double> vec)
。
它在评论中说 grade
函数不会复制其参数,因为 median
函数会复制它的参数。为什么会这样呢?
根据我的理解,你不能将 const 传递给非 const,因为这需要写访问。
这是代码:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
using std::cin;
using std::cout;
using std::domain_error;
using std::endl;
using std::istream;
using std::ostream;
using std::setprecision;
using std::sort;
using std::streamsize;
using std::string;
using std::vector;
// compute the median of a `vector<double>'
// note that calling this function copies the entire argument `vector'
double median(vector<double> vec)
{
#ifdef _MSC_VER
typedef std::vector<double>::size_type vec_sz;
#else
typedef vector<double>::size_type vec_sz;
#endif
vec_sz size = vec.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(vec.begin(), vec.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}
// compute a student's overall grade from midterm and final exam grades and homework grade
double grade(double midterm, double final, double homework)
{
return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}
// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
// this function does not copy its argument, because `median' does so for us.
double grade(double midterm, double final, const vector<double>& hw)
{
if (hw.size() == 0)
throw domain_error("student has done no homework");
return grade(midterm, final, median(hw));
}
// read homework grades from an input stream into a `vector<double>'
istream& read_hw(istream& in, vector<double>& hw)
{
if (in) {
// get rid of previous contents
hw.clear();
// read homework grades
double x;
while (in >> x)
hw.push_back(x);
// clear the stream so that input will work for the next student
in.clear();
}
return in;
}
int main()
{
// ask for and read the student's name
cout << "Please enter your first name: ";
string name;
cin >> name;
cout << "Hello, " << name << "!" << endl;
// ask for and read the midterm and final grades
cout << "Please enter your midterm and final exam grades: ";
double midterm, final;
cin >> midterm >> final;
// ask for the homework grades
cout << "Enter all your homework grades, "
"followed by end-of-file: ";
vector<double> homework;
// read the homework grades
read_hw(cin, homework);
// compute and generate the final grade, if possible
try {
double final_grade = grade(midterm, final, homework);
streamsize prec = cout.precision();
cout << "Your final grade is " << setprecision(3)
<< final_grade << setprecision(prec) << endl;
} catch (domain_error) {
cout << endl << "You must enter your grades. "
"Please try again." << endl;
return 1;
}
return 0;
}
看一下这一行:
return grade(midterm, final, median(hw));
hw
这里是一个对向量的 const 引用,它被传递给 median
。虽然确实无法通过 const 引用修改对象,但您仍然可以通过 const 引用创建对象的副本。因此,由于 median
需要更改 vector
(通过对它进行排序),它会为自己创建一个副本(该副本将在后台隐式创建)并对其进行排序。
为什么会这样呢?根据我的理解,你不能将 const 传递给 非常量,因为需要写访问。
是和否,您不能写入
const
变量是正确的,但这不是这里发生的情况。
return grade(midterm, final, median(hw));
这里对
median
的调用为我们完成了这项工作。 median
需要一个 std::vector
,编译器会在后台将其传递给它。它复制 const &
引用的向量,并将该副本传递给 median
。请记住,编译器只需要读取访问权限即可复制,而不是写入,这正是 hw
为我们提供的。