我有三个文件 - main.cpp,file1.cpp和headerFile.h。
file1是 -
.listeleme-field-sayfa {
border-top: 1px solid #ccc;
font: 12px sans-serif;
position: fixed;
bottom: 0px;
z-index: 1000;
background: white;
}
headerFile.h是 -
#include<iostream>
using namespace std;
void function1(){
cout<<"this is function1 from file1"<<endl;
}
main.cpp文件是 -
#ifndef HEADERFILE_H_
#define HEADERFILE_H_
void function1();
#endif /* HEADERFILE_H_ */
在此阶段之前,main.cpp文件不知道function1()
现在人们说当编译器在主文件中遇到#include<iostream>
using namespace std;
#include "headerFile.h"
int main(){
function1();
cout<<"this is main function from mainFile"<<endl;
return 0;
}
时,它只是将headerFile.h的代码复制到主文件中,因此主文件变为 -
#include "headerFile.h"
现在,编译器仍然不知道function1()的定义。这个定义是如何解决的?请解释一下。
答案 0 :(得分:3)
在编译main.cpp
时,编译器仍然不知道函数定义(根据编译器/平台,它变为main.obj
或者simillar)。它只需知道headerFile.h
中声明提供的该函数的签名(其名称,返回值,参数)。在编译的目标文件中将写入(通过机器语言)。
这里,用户正在调用一些function1,请链接器找到它的地址并将其插入那里。
现在,当您将file1.cpp
汇编到file1.obj
时,file1.obj
将包含已编译的function1
。
最后,当您将这两个文件链接到可执行文件(或库)时,链接器将解决仅调用已声明(但未定义)函数的所有问题。所以引用的部分将成为
这里,用户正在调用function1,它的定义位于0x0123ABC。
但是,如果你这样做,提供带有函数调用的目标文件,而这些函数调用无法解决,那么你会得到一个链接器错误(类似于)
/tmp/ccwckoGI.o:在函数
main
中:
/home/user/file.cpp:5:对foo()
的未定义引用
答案 1 :(得分:1)
头文件 - headerFile.h
包含函数的声明,并且必须附带源文件 - headerFile.cpp
。
现在,当你执行#include "headerFile.h"
时,函数的声明变得已知,因此可以编译代码。此时 - 编译main.cpp
时,main.obj
没有函数的定义。在编译完每个.cpp文件并制作.obj
个文件后,linker
将它们链接在一起,为您提供程序。
答案 2 :(得分:0)
// headerFile.h
#ifndef HEADERFILE_H_
#define HEADERFILE_H_
// add extern to tell the compiler that this function definition is in other file, yes it is in file1, complied into file1.obj
extern void function1();
#endif /* HEADERFILE_H_ */
链接器将在file1.obj中找到function1()的定义。您当然应该添加到构建命令中。