如果需要使用我们自己的带有声明的头文件和带有定义的cpp文件来编译C
或CPP
程序,我们需要在编译命令中包含带有定义的cpp文件(参见{ {3}})。但是,当我们编写#include <iostream>
时,我们不会在iostream.cpp
等编译语句中包含g++ main.cpp iostream.cpp -o main
。
如果我们编写自定义声明文件,例如hello.hpp
带有类声明,hello.cpp
带有定义,我们需要在包含g++ main.cpp hello.cpp -o main
之后使用hello.hpp
编译它main.cpp
文件中的标头。这是为什么?
编辑:我们是否可以模仿标准模板库对我们的自定义标头和cpp文件的行为,这样我们所要做的只是包含标头和声明自动获取编译?如果是,那怎么样?如果不是,为什么不呢?
答案 0 :(得分:5)
标准库正在隐式链接。所以
g++ main.cpp -o main
真的是
g++ main.cpp -o main -lstdc++ -lc
其中libstdc++
是c ++标准库,libc
是c标准库。其他库需要明确链接(例如libm
)。
如果您将编译和链接步骤分开,则会更加清晰:
g++ -c main.cpp -o main.o
g++ -c other.cpp -o other.o
g++ main.o other.o /usr/lib/libstdc++.a /usr/lib/libc.a -o main
这里我们将main()
函数定义和其他定义(other.cpp
)编译到目标文件中,并将它们与标准库中现有的编译函数/类/变量定义相结合。
请参阅Shared Library Creation上的TLDP页面
Static Library Creation有关定义文件(.c
和.cpp
)如何转换为库的详细信息。
答案 1 :(得分:1)
首先,检查在this post包含<filename>
和"filename"
之间的区别:
对于#include“filename”,预处理器在与包含该指令的文件相同的目录中进行搜索。这个方法是 通常用于包含程序员定义的头文件。
对于#include&lt;文件名&GT;预处理器在实现中搜索 依赖方式,通常在预先指定的搜索目录中 编译器/ IDE。此方法通常用于包括标准库 头文件
您包含文件的事实并不意味着您正在编译文件。事实上,通过包含你正在解决包含文件的语法引用,如类声明(在C ++中),常见变量,结构,枚举和函数调用。这将避免代码获取未引用的对象错误,从而破坏编译过程。
使用这些引用编译代码并不意味着编译原始引用的代码。以下面的例子为例:
mycode.cpp
包括myclass.hpp
,如:
#include "myclass.hpp"
如果引用正确,您可以使用以下命令编译它:
g++ mycode.cpp
您将拥有mycode.cpp
(一个名为mycode.o
的目标文件)的编译代码,但不会编译代码myclass
。 mycode.cpp
已正确编译,因为它具有对myclass
对象/函数/等的引用,但这并不意味着myclass
已编译(您还没有对象)档案myclass.o
)。
如果您链接编辑mycode.cpp
,则会有几个缺少的引用,因为没有myclass
已编译的代码。
如果您选择:
g++ mycode.cpp myclass.cpp
它会生成mycode.o
和myclass.o
的目标文件,以后可以链接在一起。
对于STL库,您只需要引用,因为它们已经编译并且可用于所谓的标准库(已经为您编译的一组对象.o
文件)。然后,liker将自动联系或者如果你正确地告诉他那样将它们联系在一起。
我建议您通过compilation -> object files -> link editing -> executable file
进程来了解这些步骤,这些步骤仅适用于编译语言。
答案 2 :(得分:1)
您需要了解编译器读取输入文件,然后预处理它们,预处理器替换所有#include语句,以便编译器本身永远不会看到它们。就真正的编译器而言,没有#include语句。然后,编译器将源语言转换为机器代码。编译器为每个输入(c或cpp)文件编写一个目标文件。目标文件中的机器码不能直接执行;它必须与其他代码链接。
最初,程序员会将程序与已经编译成目标文件库的其他目标文件链接起来。多个目标文件静态链接在一起以生成可执行文件,并且可以对许多可执行文件执行此操作。换句话说,许多目标文件中的每一个都可能存在多次,对于许多可执行文件中的每一个都存在一次。这意味着当某些内容发生变化时,有时必须再次链接许多使用相同目标文件的程序。后来的程序员了解到它有助于动态链接到目标文件,这就是动态链接库。
编译程序时,编译器包含链接器链接到其他库的指令,主要是“C运行时”(CRT)。链接可以是静态链接或动态链接。此外,标头提供有关CRT的信息。大多数标准库(std命名空间)实际上都在标题中,例如在“iostream”中,并使用您的程序进行编译。标题中没有的任何内容都在某个CRT库中。
因此,iostream.cpp的等价物可能在您自己的程序中,例如main.cpp,或者已经编译过,并且位于与您的程序链接的CRT库中。