浅析头文件保护和宏的作用域
2015-12-16 17:17
169 查看
导言:
最近在看C++的编译链接过程:编译分为预处理和汇编阶段。预处理阶段主要对宏进行处理1)将#include宏包含的文件整体拷贝过来;2)将#define定义的宏替换;3)根据条件宏#ifdef决定取舍那段代码。
问题:
本来是想提一个问题的,可是写着写着就写了一段代码测试去了,测着测着,就想明白了。
我的原始问题是这样的:假设有类A,头文件A.h,实现文件A.cpp;还有一个B.cpp包含了A.h.在编译B.cpp时,编译器会发现A.h的头文件保护宏已经定了(因为A.cpp中也包含了A.h,假设A.cpp先于B.cpp定义),那么B.cpp也就不会添加类A的定义代码。这跟B.cpp不#include "A.h"有什么区别呢?(显然不#include "A.h"会报错:未定义的标识符)。
当然我这个问题的描述就错了,错在我没有弄明白源文件中的宏的作用域仅先于当前文件。也就是说,B.cpp在编译时会发现A.h的头文件保护宏是没有定义的,仍然会将类A的定义代码直接拷贝过来。
总结:
1. 类的定义相当于声明,声明可以有多个,但定义只能有一个。这就是为什么类的定义文件不要有函数的实现的原因。
2. 头文件保护是为了防止同一个源文件多次包含该头文件(会出现“类型重定义”的错误)。
3.我发现这样也不会出错:再写一个文件AA.h,其中定义一个类A(名称与之前的A一样),但这个A的定义稍有不同。B.cpp包含AA.h。
4.那么,A.cpp和B.cpp都包含了类A的定义,至于在连接阶段为什么不会出错,我还在思考,也许就是不会出错。
最近在看C++的编译链接过程:编译分为预处理和汇编阶段。预处理阶段主要对宏进行处理1)将#include宏包含的文件整体拷贝过来;2)将#define定义的宏替换;3)根据条件宏#ifdef决定取舍那段代码。
问题:
本来是想提一个问题的,可是写着写着就写了一段代码测试去了,测着测着,就想明白了。
我的原始问题是这样的:假设有类A,头文件A.h,实现文件A.cpp;还有一个B.cpp包含了A.h.在编译B.cpp时,编译器会发现A.h的头文件保护宏已经定了(因为A.cpp中也包含了A.h,假设A.cpp先于B.cpp定义),那么B.cpp也就不会添加类A的定义代码。这跟B.cpp不#include "A.h"有什么区别呢?(显然不#include "A.h"会报错:未定义的标识符)。
当然我这个问题的描述就错了,错在我没有弄明白源文件中的宏的作用域仅先于当前文件。也就是说,B.cpp在编译时会发现A.h的头文件保护宏是没有定义的,仍然会将类A的定义代码直接拷贝过来。
总结:
1. 类的定义相当于声明,声明可以有多个,但定义只能有一个。这就是为什么类的定义文件不要有函数的实现的原因。
2. 头文件保护是为了防止同一个源文件多次包含该头文件(会出现“类型重定义”的错误)。
3.我发现这样也不会出错:再写一个文件AA.h,其中定义一个类A(名称与之前的A一样),但这个A的定义稍有不同。B.cpp包含AA.h。
4.那么,A.cpp和B.cpp都包含了类A的定义,至于在连接阶段为什么不会出错,我还在思考,也许就是不会出错。
相关文章推荐
- ESXI5 运行一断时间后,客户端连接不上的问题解决
- 使用gulp创建ajax模拟请求
- React Native (一) --React 入门
- 【ITOO】--项目系统架构图
- Photoshop 快捷键设置之进化
- Android多媒体编程
- CF 600C 贪心+字符串
- Linux下配置Caffe及其Python接口全过程记录(Ubuntu15.10_amd64+CUDA7.5)及训练mnist数据集
- 使用jQuery的hover事件在IE中不停闪动的解决方法
- python contextlib.py
- 新建一个Model类的注意事项
- UWP深入学习五: 传感器与搜索、共享及链接
- 关于分布式锁的问题
- PAT 1047. 编程团体赛
- logback 簡介
- 你不得不读的书籍清单
- word导出功能
- Error: Failed to create feature class. Table already registered
- UICollectionView详解
- Android Studio ADB not responding.//adb.exe程序启动不起来,如何处理