C++ 中的编译流程
Compilation flow in C++
考虑以下代码:
//header.h
#pragma once
class A
{
public:
A();
void f();
};
//header.cpp
#include "header.h"
A::A(){}
void A::f(){}
//main.cpp
#include "header.h"
int main()
{
A a;
a.f();
}
那么编译器如何知道 constructor
和 f
函数的声明到底在哪里,因为 main.cpp
中只包含 header.h
?为什么当 class A
是模板时它找不到相同的函数??
让我给你看这张图片:
(来源:mcmahon at faculty.cs.niu.edu)
编译过程是这样的:
C++ 预处理器将包含的头文件的内容复制到源代码文件中,生成宏代码,并用它们的值替换使用#define 定义的符号常量。
C++预处理器生成的扩展源代码文件被编译成平台的汇编语言。
编译器生成的汇编代码被汇编成平台的目标代码。
汇编程序生成的目标代码文件与用于生成可执行文件的任何库函数的目标代码文件链接在一起。
编译单元不需要定义,只需要声明。
链接器将确保所有函数定义都可以从所有构成的编译单元中找到。
模板 class 仅在使用时实例化,并且是在 function-by-function 的基础上。正是出于这个原因,模板 classes 倾向于在 headers.
中完全定义
考虑以下代码:
//header.h
#pragma once
class A
{
public:
A();
void f();
};
//header.cpp
#include "header.h"
A::A(){}
void A::f(){}
//main.cpp
#include "header.h"
int main()
{
A a;
a.f();
}
那么编译器如何知道 constructor
和 f
函数的声明到底在哪里,因为 main.cpp
中只包含 header.h
?为什么当 class A
是模板时它找不到相同的函数??
让我给你看这张图片:
(来源:mcmahon at faculty.cs.niu.edu)
编译过程是这样的:
C++ 预处理器将包含的头文件的内容复制到源代码文件中,生成宏代码,并用它们的值替换使用#define 定义的符号常量。
C++预处理器生成的扩展源代码文件被编译成平台的汇编语言。
编译器生成的汇编代码被汇编成平台的目标代码。
汇编程序生成的目标代码文件与用于生成可执行文件的任何库函数的目标代码文件链接在一起。
编译单元不需要定义,只需要声明。
链接器将确保所有函数定义都可以从所有构成的编译单元中找到。
模板 class 仅在使用时实例化,并且是在 function-by-function 的基础上。正是出于这个原因,模板 classes 倾向于在 headers.
中完全定义