头文件如何提供函数定义

How are function definitions provided by the header file

本文关键字:函数 定义 何提供 文件      更新时间:2023-10-16

我有三个文件-main.cpp、file1.cpp和headerFile.h。

文件1是-

#include<iostream>
using namespace std;
void function1(){
    cout<<"this is function1 from file1"<<endl;
}

headerFile.h是-

#ifndef HEADERFILE_H_
#define HEADERFILE_H_
void function1();
#endif /* HEADERFILE_H_ */

main.cpp文件是-

#include<iostream>
using namespace std;
#include "headerFile.h"
int main(){
function1();
    cout<<"this is main function from mainFile"<<endl;
    return 0;
}

在此阶段之前,函数1()对于main.cpp文件是未知的
现在人们说,当编译器在主文件中遇到#include "headerFile.h"时,它只是将headerFile.h的代码复制到主文件中,
因此主文件变成了-

#include<iostream>
using namespace std;

#ifndef HEADERFILE_H_
#define HEADERFILE_H_
void function1();
#endif /* HEADERFILE_H_ */

int main(){
function1();
    cout<<"this is main function from mainFile"<<endl;
    return 0;
}

现在,这里函数1()的定义对于编译器来说仍然是未知的。这个定义是如何解决的?请解释。

编译main.cpp时,编译器仍然不知道函数定义(根据编译器/平台的不同,函数定义变为main.obj或类似)。它只需要知道该函数的签名(其名称、返回值、参数),由headerFile.h中的声明提供。在编译的对象文件中,将(通过机器语言)进行编写。

在这里,用户正在调用某个函数1,请链接器,找到它的地址并将其插入其中。

现在,当您将file1.cpp编译为file1.obj时,file1.obj将包含已编译的function1

最后,当您将这两个文件链接到可执行文件(或库)中时,链接器将解决只调用已声明(但未定义)函数的所有问题。因此引用的部分将成为

在这里,用户正在调用函数1,它的定义位于0x0123ABC。

然而,如果您确实为对象文件提供了无法解决的函数调用,您将得到一个链接器错误(类似于)

/tmp/ccwckoGI.o:在函数main中:
/home/user/file.cpp:5:对foo() 的未定义引用

头文件-headerFile.h包含函数的声明,并且必须附带一个源文件headerFile.cpp

现在,当您执行#include "headerFile.h"时,函数的声明将变为已知,因此可以编译代码。此时,在编译main.cpp时,main.obj没有函数的定义。在编译了每个.cpp文件并制作了.obj文件后,它们通过linker链接在一起,为您提供程序。

// 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()的定义。当然,您应该将其添加到构建命令中。