Defining C++ Functions Inside Header Files

2020-02-02 08:18发布

问题:

I'm Wondering if it's a good practice to store c++ regular functions, not methods(the ones in classes) inside header files.

Example:

#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED

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

#endif

And Use it like this:

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

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

Is This Good a good practice? Thanks

回答1:

If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.

The when you build, you first compile the source files to object files, and then you link the object files into the final executable.


Example code:

  • Header file

    #ifndef FUNCTIONS_H_INCLUDED
    #define FUNCTIONS_H_INCLUDED
    
    int add(int a, int b);  // Function prototype, its declaration
    
    #endif
    
  • First source file

    #include "functions.h"
    
    // Function definition
    int add(int a, int b)
    {
        return a + b;
    }
    
  • Second source file

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

How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.

If you are building from the command line in e.g. Linux or OSX, then you do like

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

The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).



回答2:

No. If you import the same header from two files, you get redefinition of function.

However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.

Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.

It's also OK to define member functions inside the class in header as C++ standard considers them as inline.



回答3:

No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.

Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.

If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.

If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.



标签: c++ function