【问题标题】:Compilation flow in C++C++ 中的编译流程
【发布时间】:2015-07-13 09:00:58
【问题描述】:

考虑下面的代码:

//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();
}

那么编译器如何知道constructorf 函数的声明究竟在哪里,因为只有header.h 包含在main.cpp 中?又为什么class A为模板时找不到相同的功能??

【问题讨论】:

标签: c++ templates compilation linker


【解决方案1】:

让我给你看这张图片:
(来源:mcmahon at faculty.cs.niu.edu

编译过程如下:

  1. C++ 预处理器将包含的头文件的内容复制到源代码文件中,生成宏代码,并将使用#define 定义的符号常量替换为它们的值。

  2. C++预处理器生成的扩展源代码文件被编译成平台的汇编语言。

  3. 编译器生成的汇编代码被汇编成平台的目标代码。

  4. 汇编器生成的目标代码文件与用于生成可执行文件的任何库函数的目标代码文件链接在一起。

【讨论】:

  • 这似乎并没有真正回答 OP 的问题?
  • 我认为这并不取决于你是否使用OP。由于 C++ 编译器用于使事情正常工作的基本规则是相同的。类定义只是“模板”,当您在代码中使用某些部分时,编译器会对其进行扩展。
  • OP == 原创海报
  • 它没有回答整个的问题,但是这张图真的很漂亮。
【解决方案2】:

编译单元不需要定义,只需要声明

链接器将确保所有函数定义都可以从所有组成的编译单元中找到。

模板类仅在使用时实例化,并且是在逐个函数的基础上进行的。正是出于这个原因,模板类往往在标头中完全定义。

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 2018-05-06
    相关资源
    最近更新 更多