Mat*_*lia 14
在比简单的Hello World更大的项目中,编写更多.cpp(技术上称为"翻译单元"),以逻辑方式分离应用程序的各个部分并减少编译时间.
请注意,不同的cpp文件没有合并在一个主.cpp中(我想你从你的问题中思考),但每个.cpp都是自己编译的; 编译器为每个.cpp生成一个对象模块(通常是.o或.obj),然后调用链接器将这些模块链接在一起以生成最终的可执行文件.
如何使这项工作?在手动调用编译器的小项目中,您可以只调用编译器在命令行上指定所有.cpps并让它重新编译所有内容并自行调用链接器.
当程序变大时,通常只委托在修改过的文件上调用编译器的任务,然后将链接器运行到某种实用程序:很多人使用Makefile,很多人只使用管理项目中所有文件的IDE.只需按一个按钮即可自动调用编译器和链接器.实际上,在不同的步骤中手动调用编译器和链接器是非常罕见的.
为了使各种模块之间的通信成为可能,C++允许使用prototypes/extern声明(通常在头文件中完成)声明函数/类/变量,而无需在当前转换单元中实际定义它们.这使编译器可以检查语法并为过程调用发出代码,并指示链接器在其他对象模块中查找这些"缺失的部分".
通常做的是将每个.cpp与.hpp(或.h,如果你是老式的:) :)标题相关联,其中包含相对于其.cpp的所有原型和声明,应该可以从其他模块访问.这样,如果A.cpp需要调用B.cpp中定义的函数,它可以简单地包含Bh
一个简单的例子可能是:
#ifndef A_CPP_INCLUDED
#define A_CPP_INCLUDED
// ^^^ these are header guards, used to avoid multiple inclusions of the same header
// Declarations
// Notice that this does not define a global variable, it just says to the compiler "in some module there's a global named in this way, let me access it"
extern int AUselessGlobalVar;
int AddFive(int In);
#endif
Run Code Online (Sandbox Code Playgroud)
#include "A.hpp" //it's useful that each .cpp includes its own .hpp, so it has all the prototypes already in place
// Actually define the var
int AUselessGlobalVar;
// Actually define the function
int AddFive(int In)
{
return In + 5;
}
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include "A.h" // now it can access all the functions/vars declared in A.h
int main()
{
std::cin>>AUselessGlobalVar;
std::cout<<AddFive(AUselessGlobalVar);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,在这个博客文章中有一个关于链接的经典模型的很好的描述,这与我们正在谈论的内容非常相关.