你曾经碰到的问题:

1.为什么有时会出现aaa已在bbb中重定义的错误?

2.为什么有时会出现无法解析的外部符号?

3.为什么有的内联函数的定义需要写在头文件中?

4.为什么对于模板,声明和定义都要写在一起?

编译单元

什么是编译单元呢?简单来说一个cpp文件就是一个编译单元。

编译单元:当一个c或cpp文件在编译时,预处理器首先递归包含头文件,形成一个含有所有 必要信息的单个源文件,这个源文件就是一个编译单元。

事实上编译每个编译单元(.cpp)时是相互独立的,即每个cpp文件之间是不知道对方的存在的(不考虑#include “xxx.cpp" 这种奇葩的写法)

编译器会分别将每个编译单元(.cpp)进行编译,生成相应的obj文件

然后链接器会将所有的obj文件进行链接,生成最终可执行文件。

内部链接与外部链接

那么什么内部链接和外部链接又是什么呢?

我们知道C++中声明和定义是可以分开的

例如 我们可以一个函数声明定义放在b.cpp中,在a.cpp只需再声明一下这个函数,就可以在a.cpp中使用这个函数了

a.cpp

void show();int main()
{show();
     return 0;
}

b.cpp

#include <iostream>
void show()
{std::cout << "Hello" << std::endl;
}

而通过之前的了解,我们知道每个编译单元间是相互独立不知道彼此的存在的

那么a.cpp又是如何知道show函数的定义的呢

其实在编译一个编译单元(.cpp)生成相应的obj文件过程中

编译器会将分析这个编译单元(.cpp)

将其所能提供给其他编译单元(.cpp)使用的函数,变量定义记录下来。

而将自己缺少的函数,变量的定义也记录下来。

所以可以认为a.obj和b.obj记录了以下的信息

然后在链接器连接的时候就会知道a.obj需要show函数定义,而b.obj中恰好提供了show函数的定义,通过链接,在最终的可执行文件中我们能看到show函数的运行。

好了让我们看下 内部链接外部链接比较正式的定义

内部连接:如果一个名称对编译单元(.cpp)来说是局部的,在链接的时候其他的编译单元无法链接到它且不会与其它编译单元(.cpp)中的同样的名称相冲突。例如static函数,inline函数等(注 : 用static修饰的函数,本限定在本源码文件中,不能被本源码文件以外的代码文件调用。而普通的函数,默认是extern的,也就是说,可以被其它代码文件调用该函数。)

外部连接:如果一个名称对编译单元(.cpp)来说不是局部的,而在链接的时候其他的编译单元可以访问它,也就是说它可以和别的编译单元交互。 例如变量就是外部链接, 全局变量。

那么回到最初的问题:

1. 为什么有时会出现aaa已在bbb中重定义的错误?

答:  你可能在不同的cpp中重复定义了一个具有外部链接的函数或变量,链接器在链接时找到了多个一样的函数或变量定义。

2. 为什么有时会出现无法解析的外部符号?

答:你可能只提供了函数或变量的声明,没有提供其定义,或者声明和定义的函数原型不一致,链接器没有找到其定义在哪里,所以在链接环节出现了无法解析的外部符号的错误。

3. 为什么有的内联函数的定义需要写在头文件中呢?

答:因为内链函数是内部链接的,如果你在b.cpp中定义这个函数,那么在a.cpp中即使有这个函数声明,但由于内联函数是内部链接的,所以b.cpp不会提供其定义。所以在链接时a.obj无法找到这个函数的定义,便会出现无法解析的外部符号的错误

4.为什么对于模板,声明和定义都要写在一起呢?

答:我们假设我们有如下结构的代码

a.h

#pragma once
template<typename T>
class A
{
public:A(const T &t);
};

a.cpp

#include "a.h"
#include <iostream>template<typename T>
A<T>::A(const T &t)
{std::cout << t << std::endl;
}

main.cpp

#include "a.h"int main()
{ A<int> a(5);return 0;
}

那么程序能否正常运行呢?答案是不能 我们首先来分析一下编译器在编译main.cpp时,只有声明,发现其缺少A<int>::a(const int& t)的定义 ,因为它不在a.h里面, 于是编译器只好寄希望于连接器, 希望它能够在其他.obj里找到定义, 而在编译器编译a.cpp时,没有用到A<int> , 模板只有被用到的时候才会被实例化, 每个编译单元是独立的,它也不知道main.cpp用了A<int> ,所以它不会提供定义,编译出来的a.obj文件中关于A 的一行二进制代码也没有,这样在链接时main.obj无法找到A<int>::a(const int& t)的定义,就会出现无法解析的外部符号的错误LNK1120 (注意, 在a.cpp 中加入一个函数用到A, void f2(){ A<int >  a(222); } ,则此问题解决  )

5.宏是内部链接还是外部链接

答:都不是,宏在预处理环节时就被替换掉了,而内部链接与外部链接是针对编译环节与链接环节而言的

Created by 黄强

C++内部链接与外部链接相关推荐

  1. 网站应该更注重内部链接还是外部链接?

    在搜索引擎上,去获取流量的最基本单位就是网页.一个网页的外部链接因素,对这个网页的排名影响很大.这个网页的外部链接,既有同一个网站的其他页面给的站内链接,也有其他网站上的网页给的站外链接.下面文章里的 ...

  2. C++中头文件(.h)和源文件(.cpp)都应该写些什么,头文件中的预编译语句作用,命名空间和头文件的区别与联系,内部链接和外部链接

    1. C++中头文件(.h)和源文件(.cpp)都应该写些什么: 总结下来就是头文件写的就是类的声明(包括类里面的成员和方法的声明)和函数的声明,但一般来说不写出具体的实现.对应的同名(可以不同名,但 ...

  3. C++声明与定义、内部链接与外部链接的意义

    一. 声明与定义 A. 大多数情况下,声明与定义是相同的,但是有少些情况下,声明并非定义,而定义又非声明: 1.是声明,但是并不是定义: 1) 声明了一个没有具体说明函数体的函数: void decl ...

  4. 内部链接和外部链接【转】

    from here 首先,我们来了解下定义: 内部连接:如果一个名称对编译单元(.cpp)来说是局部的,在链接的时候其他的编译单元无法链接到它. 外部连接:如果一个名称对编译单元来说不是局部的,而在链 ...

  5. 超链接的内部链接和外部链接

    <a href="http://www.baidu.com">外部链接</a> <a href="a.html">内部链接& ...

  6. 什么是内部链接和外部链接

    <a href="http://www.shakespeare.co.uk/henry.htm">外部链接</a> <a href="a.h ...

  7. 各类链接(外部链接、内部链接……)的使用方法合集

    上篇讲了"网站SEO关键词布局操作大全",这篇讲链接,网站是通过一个一个链接搭建到一块的,所有网站之间以及网站和用户之间也都是通过链接进行联系起来的,同样也是搜索引擎爬取和识别的线 ...

  8. HTML中超链接:内部链接、外部链接、空链接、锚点链接的区分

    ①.内部链接:在自己的网站中,网页之间相互跳转. <a href="a.html" target="_blank">跳转到a.html</a& ...

  9. 超链接——内部链接、外部链接、锚点链接、下载链接、空链接、其他元素链接

    一.内部链接 first.html 和second.html在同一文件内,想在first.html中通过超链接跳转到second.html中,可以通过内部链接实现. <a href=" ...

  10. C++编译单元 内部链接 外部链接

    文章目录 编译单元 内部链接 外部链接简单解释 代码解释 外部链接 内部链接 C++ 中的内部链接 和外部链接 类型 编译单元 内部链接 外部链接简单解释 这是一个最简单最表面的解释,深入的解释应该要 ...

最新文章

  1. PAT(甲级)2019年秋季考试 7-2 Merging Linked Lists
  2. ReactNative之从HelloWorld中看环境搭建、组件封装、Props及State
  3. 零基础入门深度学习的五篇经典教程
  4. js中同时得到整数商及余数_js和vue实现时分秒倒计时的方法
  5. 初探Oracle--Oracle查询操作
  6. mysql查看脚本错误位置_记一次mysql启动不了查找经历
  7. Factory Method 抽象工厂模式(创建型)
  8. win10 DOS命令操作
  9. 金山助手流氓软件-被进程sjk_daemon.exe坑死
  10. thinkserver t340 u盘安装centos 遇到的问题
  11. 图片文件探究1:各种图片文件十六进制的文件头和文件尾
  12. 后端 学习 前端 Vue 框架基础知识
  13. EOS Royale游戏遭受黑客攻击,黑客目前共获利18000eos
  14. PDM,读《长尾理论》
  15. python有四个数字_Python生成0-9任意4位数字组合的方法
  16. 有这5款开源软件,语音转文字很简单!
  17. 【专辑下载】Hillsong 所有专辑列表
  18. html文本环绕’,css如何使文字环绕显示
  19. cloc rpm安装包制作
  20. input框聚焦时,提示文字上移

热门文章

  1. 多视图信息瓶颈表征学习
  2. 密码学知识-加密介绍-1
  3. 运营商推无限流量卡:这是不是一记昏招?
  4. Caused by: java.lang.NoSuchMethodError
  5. 超高度近视合并白内障患者如何重返年轻优视力
  6. 计算机锁屏如何取消密码,Win10锁屏密码怎么取消?Win10系统取消锁屏密码的方法教程...
  7. 2020年android studio ------jni常用函数总结
  8. 用什么工具可以免费下载720云VR全景图
  9. 百宝云Post与Get事件教程
  10. IDLE的介绍和使用