如何创建类似于标准库 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
我正在尝试创建一个 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