快速问题。
我正在努力确定C++,今天我花了几个小时处理双重定义链接器错误("这已经定义好了!"),我终于意识到这是因为我有这样的布局:
-
main.cpp
#include Dog.cpp
-
Dog.cpp
#include Dog.h
-
Dog.h
// (Dog class and prototype of test function)
现在我已经通过在main.cpp.中包含Dog.h而不是Dog.cpp来澄清这一点
通过包含.h文件,具有相同前缀的.cpp文件是否与程序一起编译
当这个程序只包含.h,没有任何关于Dog.cpp的参考时,我大吃一惊。我花了很长时间在谷歌上搜索,但没有任何答案真正帮助我理解发生了什么。
编辑:我忘记添加我在.h中原型化的内容,并在.cpp中定义了类的函数,这就是我出现"已定义"错误的原因。
通过包含.h文件,具有相同前缀的.cpp文件是否与程序一起编译?当程序运行时只包含.h,没有任何对Dog.cpp.的引用时,我大吃一惊
没有。
您的程序是分阶段构建的。
-
对于编译阶段,在每个翻译单元中只需要声明(大致相当于已解析
#include
的单个.cpp文件)。声明之所以存在,首先是作为一种"承诺",即稍后将找到完整的函数定义。g++ -c Dog.cpp # produces `Dog.o` g++ -c main.cpp # produces `main.o`
-
对于链接阶段,符号在翻译单元之间解析。你必须将编译Dog.cpp和编译main.cpp的结果链接在一起(也许你的IDE是为你做这件事的?),这个链接过程会在它们之间找到所有正确的函数定义,以生成最终的可执行文件。
g++ Dog.o main.o -o program # produces executable `program`
(要么是这样,要么你实际上还没有进入链接阶段,只有一个对象文件(Dog.o);你不能执行它,部分原因是它没有包含所有的函数定义。)
这两个阶段可以同时完成,使用"简写":
g++ Dog.cpp main.cpp -o program # compiles, links and produces executable
您没有指定如何编译它。如果您使用的是IDE,并且自动为项目添加了新的.h和.cpp,那么它将自动编译并链接。
使可执行文件运行有两个阶段:编译和链接。编译是对代码进行解释并将其翻译为较低级别的代码的地方。链接是解析您使用的所有函数的地方。这就是出现重复函数错误的地方。
包含不会自动导致编译,不会。
事实上,实际的编译器根本看不到#include
语句。它被前面的一个步骤(称为预处理器)删除。
如果您从未编译过Dog.cpp
文件,我不确定它是如何构建的。您是否引用了该文件中定义了代码的任何对象?