4

我有以下 3 个文件(1 个 *.cpp 和 2 个 *.hpp):

主程序文件:

// test.cpp

#include<iostream>
#include"first_func.hpp"
#include"sec_func.hpp"

int main()
{
    double x;
    x = 2.3;
    std::cout << sec_func(x) << std::endl;
}

- first_func.hpp 头文件:

// first_func.hpp

...

double  first_func(double x, y, x)
{

    return x + y + x;
}

- sec_func.hpp 标头:

// sec_func.hpp

...

double sec_func(double x)
{
        double a, b, c;
        a = 3.4;
        b = 3.3;
        c = 2.5;

        return first_func(a,b,c) + x;
}

如何从 sec_func.hpp 文件中正确调用 first_func?

4

3 回答 3

7

对于大多数函数,实现应该驻留在编译单元中,即一个将自行编译并编译一次的文件。

头文件不能自己编译*,而是被多个编译单元包含。

这就是为什么您的函数定义应该驻留在编译单元(如 .cpp)而不是头文件中的原因。头文件应该只包含声明(即没有正文),足以让其他编译单元知道如何调用它们。


为了完整起见,通常需要在 headers 中定义的函数(作为例外)是:

  • inline职能
  • 模板函数**(也是类)

脚注:

*头文件实际上可以预编译,但这是加快编译速度的解决方案,并且不会改变它们的用途;不要对此感到困惑。
**如果您使用显式模板实例化,您可以将模板函数定义放在标头之外,但这种情况很少见;关键是每个想要实例化模板(对其应用参数)的编译单元都需要有完整的定义,这就是模板函数定义也进入标题的原因。

于 2012-07-22T18:19:09.987 回答
5

将函数定义放在.hpp文件中是一种不好的做法。您应该只在那里放置函数原型。像这样:

first_func.hpp:

double  first_func(double x, double y, double x);

first_func.cpp:

double  first_func(double x, double y, double x)
{
    return x + y + x;
}

第二个功能相同。

然后,无论你想在哪里调用你的first_func,你只需first_func.hpp在该cpp模块中包含相应的,然后编写调用。

因此,您的每个模块都包含hpp所有声明和cpp定义(即主体)。当您需要从此模块中引用某些内容时,您可以包含它hpp并使用名称(常量、变量、函数等)。

然后您必须将所有内容链接在一起:

gcc main.cpp first_func.cpp second_func.cpp -o program
于 2012-07-22T18:15:11.687 回答
3

要在标头中定义一个函数,您必须标记它inline以防止多个定义。

如果您想这样做而不是将实现分离到单独的文件中,则需要在调用函数之前提供原型(通过包含标头(首选)或自己声明函数)。

// sec_func.hpp

#include "first_func.hpp"
//or
double  first_func(double x, y, x); //declaration

double sec_func(double x)
{
        double a, b, c;
        a = 3.4;
        b = 3.3;
        c = 2.5;

        return first_func(a,b,c) + x;
}
于 2012-07-22T18:17:46.487 回答