我是一名学生程序员,使用“Accelerated C ++”一书学习我的第一语言。我正处于作者解释头文件和包含函数的源文件的位置。在本书提供解释的练习中,作者具有包含函数定义的头文件,但它似乎是多余的,因为源文件也具有函数的定义。在编写C ++时,这种情况下头文件的重点是什么?
示例:头文件。
#ifndef MEDIAN_H
#define MEDIAN_H
#include <vector>
double median(std::vector<double>);
#endif // MEDIAN_H
然后源文件包含确定成绩中位数的函数:
// source file for the `median' function
#include <algorithm> // to get the declaration of `sort'
#include <stdexcept> // to get the declaration of `domain_error'
#include <vector> // to get the declaration of `vector'
using std::domain_error; using std::sort; using std::vector;
#include "median.h"
// 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];
}
即使源已经有vector<double> vec
定义,median.h也会被复制到中值函数源文件中
这本书解释它是无害的,实际上是一个好主意。但我只是想更好地了解这种冗余的原因。任何解释都会很棒!
答案 0 :(得分:2)
除了实际实现相关功能的文件之外,文件还包含头文件的用途。从本质上讲,您需要告诉C ++编译器存在哪些函数,以及它们调用它们的样子。
例如,假设我有一个函数doStuff.cpp:
#include "median.h"
std::vector<double> my_vector;
double my_median;
void do_stuff(){
my_median=median(my_vector);
}
C ++编译器需要知道函数median()
具有您的特定参数并返回值而不是其他人的median()
。
答案 1 :(得分:0)
是的,这是多余的,但标准做法。 C / C ++编译器在使用函数之前需要声明。在某些情况下,这意味着您必须在实现之前拥有声明,例如,如果您具有相互递归的函数。如果项目中有多个文件,那么您还需要在另一个文件中包含您正在使用的函数声明 - 最简单的方法是将它们分开。
也就是说,声明/实现也是独立的,以便在库中可重用。想象一下,你编写了一个非常大的有用函数库,而其他人想要使用它们。他们需要为编译器提供他们将使用的函数的声明,因此他们使用你的.h文件。