如何创建类似于标准库 header 的 header,以便可以在不链接 header 中所有 object 函数文件的情况下编译程序?

How to create a header like a standard library header, so that program can be compiled without linking all object files of functions in the header?

我正在尝试创建一个 header 文件,它可以像 #include "sort.h "
包含header的程序可以正常编译
g++ main.cpp
无需 link header 中的每个 object 函数文件和 main.

g++ -c main.cpp insertion_sort.cpp merge_sort.cpp


g++ main.o merge_sort.o insertion_sort.o

所以我必须 link header. 中每个函数的每个 object 文件,或者是他们的另一种方式?
header 文件:

//sort.h file
#ifndef sort_h
#define sort_h

    void insertion_sort(int *a,int n);
    void merge_sort(int *a,int n);

    //I want to include more functions

    #endif

如何像 cmath 或 stdlib.h 这样的普通 header 使用我的 header?

您的印象似乎是您从标准库 headers 获得的东西没有对应的 object files/library 需要链接的文件。这是错误的.

标准库链接到您的应用程序,只是编译器会自动为您完成。您不必手动告诉它这样做。

您的应用程序还需要可用的标准库才能 运行。这就是为什么您必须在要 运行 使用 Visual Studio 构建的程序的计算机上安装 Microsoft 可再发行组件。其他编译器有类似的要求,您需要将它们的 run-time 库与您的应用程序一起分发。

简而言之;标准库与其他库没有什么不同,除了编译器在幕后为您链接它之外。

您可以编写完全由头文件组成的模板函数。然后,您不需要任何 .cpp 文件,也不需要 link 到目标文件。虽然这不是所问问题的直接解决方案,但它是 "not linking every single object file for every function".

的一种方式

全部放在一起

如果我们举个例子,你可以尝试改变你的sort.h文件如下

//sort.h file
#ifndef sort_h
#define sort_h

    template <typename T>
    void insertion_sort(T* a,int n) {
        // insertion sort implementation goes here
    }

    template <typename T>
    void merge_sort(T* a,int n) {
        // merge sort implementation goes here
    }

#endif

当您在此处将排序例程编写为模板函数时,您的函数必须足够通用以适应通用 T 类型。一般来说,对于排序例程,T 必须小于可比性。

分离接口和实现

如果您不喜欢将文档、接口和实现全部放在一个地方,您可以先声明函数及其文档。然后,您可以在下面或可能在其他文件中定义它。所以,以下也是可能的:

//sort.h file
#ifndef sort_h
#define sort_h

    /**
     *  Function documentation
     */
    template <typename T>
    void insertion_sort(T* a,int n);

    /**
     *  Function documentation
     */
    template <typename T>
    void merge_sort(T* a,int n);


#include "insertion_sort.h"
#include "merge_sort.h"
#endif

//insertion_sort.h file
#ifndef insertion_sort_h
#define insertion_sort_h

    template <typename T>
    void insertion_sort(T* a, int n) {
        // insertion sort implementation goes here
    }

#endif

//merge_sort.h file
#ifndef merge_sort_h
#define merge_sort_h

    template <typename T>
    void merge_sort(T* a, int n) {
        // merge sort implementation goes here
    }

#endif

有些人喜欢将模板头实现文件称为.tpp文件。这取决于您的喜好。

使用来自 main.cpp

您可以使用 main.cpp 中的第一个或第二个选项,如下所示:

//main.cpp
#include "sort.h"
#include <vector>

int main() {
    std::vector<int> vec_int;
    // fill vector

    insertion_sort(&vec_int[0], vec_int.size());

    std::vector<double> vec_double;
    // fill vector

    merge_sort(&vec_double[0], vec_double.size());
}

正在编译

由于我们没有使用任何cpp文件,现在编译main.cpp应该和

一样简单
g++ -Wall -Wextra -g main.cpp

假设main.cpp和我们的头文件在同一个目录下。如果头文件在某个名为 include 的目录中,那么我们使用

进行编译
g++ -Wall -Wextra -g -Iinclude main.cpp