1

我是一名学生程序员,通过“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];
}

中位数.h 被复制到中位数函数源文件中,即使源已经有定义vector<double> vec 本书解释它是无害的,实际上是一个好主意。但我只是想更好地了解这种冗余的原因。任何解释都会很棒!

4

2 回答 2

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().

于 2013-03-04T03:52:07.947 回答
0

是的,这是多余的,但标准做法。C/C++ 编译器需要在使用函数之前进行声明。在某些情况下,这意味着您在实现之前绝对必须有一个声明,例如,如果您有相互递归的函数。如果您在一个项目中有多个文件,那么您还需要包含您在另一个文件中使用的函数的声明——最简单的方法是将它们分开。

也就是说,为了在库中的可重用性,声明/实现也是分开的。想象一下,您编写了一个非常大的有用函数库,而其他人想要使用它们。他们需要向编译器提供他们将使用的函数的声明,因此他们使用您的 .h 文件。

于 2013-03-04T03:52:17.680 回答