在头文件中定义C ++函数是否是一种好习惯?

问题描述 投票:19回答:3

我想知道在头文件中存储C ++常规函数而不是方法(类中的方法)是否是一种好习惯。

示例:

#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED

int add(int a, int b)
{
   return a + b;
}

#endif

并像这样使用它:

#include <iostream>
#include "Functions.h"

int main(int argc, char* args[])
{
    std::cout << add(5, 8) << std::endl;
    return 1;
}

这是一个好习惯吗?预先感谢!

c++ function header-files
3个回答
34
投票

如果要在多个源文件(或更确切地说是translation units)中使用函数,则将函数declaration(即函数原型)放置在头文件中,并将definition在一个源文件中。

构建时,首先将源文件编译为目标文件,然后将目标文件链接到最终的可执行文件中。


示例代码:

  • 头文件

    #ifndef FUNCTIONS_H_INCLUDED
    #define FUNCTIONS_H_INCLUDED
    
    int add(int a, int b);  // Function prototype, its declaration
    
    #endif
    
  • 第一个源文件

    #include "functions.h"
    
    // Function definition
    int add(int a, int b)
    {
        return a + b;
    }
    
  • 第二源文件

    #include <iostream>
    #include "functions.h"
    
    int main()
    {
        std::cout << "add(1, 2) = " << add(1, 2) << '\n';
    }
    

如何构建它在很大程度上取决于您的环境。如果您使用的是IDE(如Visual Studio,Eclipse,Xcode等),则将所有文件放在正确位置的项目中。

例如,如果您是从命令行构建的, Linux或OSX,那么您喜欢

$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program

标志-c告诉编译器生成目标文件,并将其命名为与源文件相同,但后缀为.o。最后一个命令将两个目标文件链接在一起以形成最终的可执行文件,并将其命名为my_program(这就是-o选项的作用,告诉输出文件的名称)。


12
投票

没有如果从两个文件导入相同的标头,则会重新定义函数。

但是,如果函数是内联的,通常是这样。每个文件都需要使用其定义来生成代码,因此人们通常将定义放在标头中。

使用static也是有效的,因为事实上静态函数不是从目标文件中导出的,因此在链接过程中不会干扰具有相同名称的其他函数。

也可以在标头的class中定义成员函数,因为C ++标准将其视为inline


10
投票

没有预处理后,每个源文件将包含头文件。然后,在链接阶段,您将遇到多个定义错误,因为您将具有同一功能的多个定义。

使用inlinestatic将消除链接错误。除非您希望函数为inline,否则最好在标头中declare函数并将其define放在单个源文件中并将其链接。

如果将函数声明为inline,则源文件中的每个函数调用都将替换为inline d函数中的代码。因此,没有定义任何额外的符号。

如果将功能声明为static,则不会从翻译单元中导出功能符号。因此,没有重复的符号。

© www.soinside.com 2019 - 2024. All rights reserved.