在C/C++中,使用#include 包含文件的时候,经常使用方法去防止重复引用,产生二义性。通常有两种方式:
第一种 #ifndef指令方式代码被重复引用,比如说:
#ifndef CODE_BLOCK_
#define CODE_BLOCK_
// code
#endif
第二种 #pragma once在想要保护的文件开头写入:
#pragma once
#ifndef 方式
特点:
- C/C++语言的标准支持,比较常用。
- 他不光可以保证一份文件不被包含两次,也能够防止不同文件的完全相同的代码被包含两次。
- 操作灵活,效率略低
- 兼容性好,因为是标准
- 可以针对代码块,也可以针对文件
a.h
#ifndef CODE_BLOCK_
#define CODE_BLOCK_
// code XXXX
#endif
b.h
#ifndef CODE_BLOCK_
#define CODE_BLOCK_
// code XXXX
#endif
可以用于大项目中的代码整理,因为他会有很多相同代码充斥在不同的模块中。
- 同样的如果自定义的宏名不小心“重名”了,两份不同文件使用相同的宏 #ifndef,那么会导致编译器找不到声明的情况。
缺点:
#ifndef 会导致编译时间相对较长。原因(面试官会问为什么?):由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,#ifndef会使得编译时间相对较长。
面试问题,编译时间过长怎么优化?考虑替换#ifndef成#pragma one
#pragma once
特点:
- 一般保证一个物理上的文件不会被两次包含
- 此方式不会出现宏名碰撞引发的奇怪问题,大型项目的编译速度也因此提高了一些
缺点:
- 无法对代码段进行声明,只能对文件
- 如果是一个文件的多个拷贝(文件名不同,内容相同),不能保证他们不被重复包含。
- 操作简单,效率高
- 兼容性不够好,低版本编译器可能不支持