c++ 中包含的方式使用Eclipse
我了解到,如果我编译 main.cpp,编译器只会将所有包含内容替换为文件的实际内容,即 #include "LongClassName.h"
替换为该文件中的文本。这是在LongClassName.h中递归完成的。最后,编译器会看到一个巨大的“虚拟”文件,其中包含所有 .cpp 和 .h 文件的完整代码。
但在实际项目中似乎要复杂得多。我查看了为我的 Qt 项目创建的 Makefile Eclipse,似乎每个名为 file.o 的文件都有一个条目,其依赖项是 file.cpp 和文件.h。所以这意味着 eclipse 单独编译每个 .cpp(?)
这是否意味着 class.cpp 对 main.cpp 中的全局内容或更高级别的类包含层次结构一无所知?
我偶然发现了这个问题尝试为长类名创建别名时。这是我的主类,我想用更短的名称调用静态函数:Ln::globalFunction()而不是LongClassName::globalFunction()
我有一个类< em>LongClassName 其标头我包含在 main.cpp 中。这是主要课程。所有其他类都包含在其中。
LongClassName.h
#define PI 3.14159265
#include <QDebug>
Class LongClassName
{
...
public:
...
private:
...
};
typedef LongClassName Ln;
LongClassName.cpp
#include "Class1.h"
#include "Class2.h"
#include "Class3.h"
/*implementations of LongClassName's functions*/
因此,我假设当编译器将代码包含在一个“虚拟”文件中时,每个类都会插入到该源代码之后,因为每个类都应该知道 Ln 是 LongClassName 的别名,
这不起作用
那么将此别名传播到所有类的最佳方法是什么?< /strong>
由于反向依赖关系,我想避免在所有类中包含 LongClassname.h 。 LongClassName 在其实现中包括所有其他类。并且几乎所有其他类都使用LongClassName的一些静态函数。
(目前我有一个单独的类 Ln 但尝试将其与 LongClassName 合并,因为它看起来更合乎逻辑。)
I learned that if I compile main.cpp the compiler simply replaces all includes with the actual content of the file i.e. #include "LongClassName.h"
with the text in that file. This is done recursively in LongClassName.h. In the end the compiler sees a huge "virtual" file with the complete code of all .cpp and .h files.
But it seems to be much more complicated in real projects. I had a look at the Makefile Eclipse created for my Qt project and it seems that there is an entry for every file named file.o and its dependencies are file.cpp and file.h. So that means that eclipse compiles each .cpp separately(?)
Does that mean that class.cpp will know nothing about global stuff in main.cpp or a class in higher include hirarchy?
I stumbled upon this problem while trying to create an alias for a long class name. It is my main class and I wanted to call static functions with a shorter name: Ln::globalFunction() instead of LongClassName::globalFunction()
I have a class LongClassName whose header I include in main.cpp. This is the main class. All other classes are included in it.
LongClassName.h
#define PI 3.14159265
#include <QDebug>
Class LongClassName
{
...
public:
...
private:
...
};
typedef LongClassName Ln;
LongClassName.cpp
#include "Class1.h"
#include "Class2.h"
#include "Class3.h"
/*implementations of LongClassName's functions*/
So I assumed that when the code is included in one single "virtual" file by the compiler every class will be inserted after this source code and because of that every class should know that Ln is an alias for LongClassName
This didn't work
So what is the best way to propagate this alias to all classes?
I want to avoid including LongClassname.h in all classes because of reverse dependencies. LongClassName includes all other classes in its implementation. And almost all the other classes use some static functions of LongClassName.
(At the moment I have a seperate class Ln but try to merge it with LongClassName because it seems more logical.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编译器知道如何将 .cpp 文件(如果是 cpp 编译器)编译为名为“目标文件”的
.o
文件,该文件是您的代码经过翻译(并且可能经过操作、优化等)的结果。到机器代码。实际上,编译器创建汇编代码,由汇编器将其翻译为机器代码。因此,每个 cpp 文件都被编译为不同的目标文件,并且对其他 cpp 文件中声明的变量一无所知,除非您在 cpp 文件或其包含的 h 文件中包含希望目标文件了解的声明。
虽然编译是为每个 cpp 单独完成的,但链接器将所有目标文件链接到单个可执行文件(或库),因此在全局命名空间中声明的变量确实是全局的,并且每个未显式放置在命名空间中的声明
命名空间放置在全局命名空间中。
您可能会受益于阅读“编译”的所有阶段,例如:http://www.network-theory.co.uk/docs/gccintro/gccintro_83.html
The compiler knows how to compile a .cpp file (if it's a cpp compiler) into a
.o
file called 'object file', which is your code translated (and probably manipulated, optimized, etc.) to a machine code. Actually the compiler creates an assembly code, which is translated to machine code by the assembler.So each cpp file is compiled to a different object file, and knows nothing about variables declared in other cpp files, unless you include declarations you want the object file to know about, either in the cpp file or in an h file it includes.
Although the compilation is done separately for each cpp, the linker links all object files to a single executable (or a library), so a variable declared in the global namespace is indeed global, and every declaration not explicitly placed in a named
namespace is placed in the global namespace.
You will probably benefit from reading about all stages of "compiling", for example here: http://www.network-theory.co.uk/docs/gccintro/gccintro_83.html
这是错误的。在
.cpp
中,您应该只包含.h
(如果您愿意,也可以包含.hpp
),几乎不包含。 cpp;
.h
通常只包含类和方法的声明,而不是它们的实际主体1(即它们的定义),因此当您编译每个.cpp
时,编译器仍然对其他.cpp
中定义的函数的定义一无所知,它只知道它们的函数的定义声明,用它它可以执行语法检查,生成函数调用的代码,...但它仍然会生成一个“不完整”的目标文件(.o
),其中将包含几个“占位符” (“这里是在其他地方定义的这个函数的地址”“这里是这个外部变量的地址”等等)在生成所有目标文件后,链接器必须采取通过将所有对象文件连接在一起并将它们的引用链接到实际代码(现在可以找到,因为我们拥有所有对象文件)来处理这些占位符。
有关经典编译+链接模型的更多信息,请参阅 在这里。
是的,就是这样。
main.cpp
不包含所有代码,仅包含声明。您不要将所有代码包含在同一个.cpp
中(例如,通过包含其他.cpp
),主要是为了减少编译时间。如果您使用标头防护装置,就不会有问题。
1. Ok, they also contain inline and template functions, but they are the exception, not the rule.
This is wrong. In
.cpp
s you should include just the.h
s (or.hpp
s if you like), almost never the.cpp
s; the.h
in general just contain the declarations of the classes and of the methods, and not their actual body1 (i.e. their definition), so when you compile each.cpp
the compiler still knows nothing about the definition of the functions defined in other.cpp
s, it just knows their declaration, and with it it can perform syntactical checks, generate code for function calls, ... but still it will generate an "incomplete" object file (.o
), that will contain several "placeholders" ("here goes the address of this function defined somewhere else" "here goes the address of this extern variable" and so on)After all the object files have been generated, it's the linker that have to take care of these placeholders, by plumbing all the object files together and linking their references to the actual code (which now can be found, since we have all the object files).
For some more info about the classical compile+link model, see here.
Yes, it's exactly like that.
main.cpp
doesn't contain all the code, but just the declarations. You don't include all the code in the same.cpp
(e.g. by including the other.cpp
s) mainly to decrease compilation time.If you use header guards, you shouldn't have problems.
1. Ok, they also contain inline and template functions, but they are the exception, not the rule.