基础知识:
(1)预编译阶段,把所有的#include "****.h"(#inclde <****.h>)用****.h的内容来替换,所以之后就而没有.h了,所有的.h的内容都已经包含进了需要它们的的.cpp中(不确定是否在预编译阶段);
(2)生成最后的exe文件是有编译、链接两步完成的,编译是源代码生成obj二进制目标文件的过程。注意:一个源代码文件(指.cpp而不是.h,此时.h已经包含进了.cpp)生成一个obj文件。编译是独立的,所以在两个独立的编译单元里可以有重名函数(重要);
(3)编译期间,只要声明的东西就可以使用,无需定义,声明可以重复,extern在编译时告诉编译单元该变量的定义在别的编译单元里面,即相当于声明,链接时,定义在整个程序中有且只有一份
方式一:
#ifndef __AAA_H__
//或写为#if !define __AAA_H__
#define __AAA_H__
... ... // 声明、定义语句
#endif
受C/C++语言标准支持
从语法上分析:
(1)预编译阶段,第一次编译,#ifndef __AAA_H__为真,执行#define __AAA_H__;
(2)第二次编译到这里,#ifndef __AAA_H__为假,跳过#define __AAA_H__,执行#endif;
优点:
(1)不仅可以保证同一个文件不被包含多次,也可以保证内容完全相同的两个文件或者代码片段不被同时包含;
(2)受C/C++语言支持,不受编译器限制;
缺点:
(1)若不同头文件的宏名不小心相同,会出现头文件存在,编译器却说找不到的情况;
(2)因为编译器需要打开文件才能确定是否有重复包含,所以大型项目会导致编译时间长;
总结:
(1)为什么不建议在.h中定义变量和函数?
因为重复声明可以,重复定义不行,.h被两个源文件重复包含后,两个编译单元分别包含同一个.h,在链接阶段导致重复定义。
但是在.h中定义static是允许的,因为static变量是模块性作用域,只会定义一次。
方式二:
#pragma once
... ... // 声明、定义语句
针对整个文件进行。
同一个文件不会被包含多次,这里的同一个文件是指物理上的文件,不包括内容相同的两个文件。
优点:
(1)不会出现宏名相同引发的冲撞问题;
(2)大型项目的编译速度相对提高;
缺点:
(1)文件名不同但是内容相同的多个文件可能会被重复包含;
(2)兼容性不太好;
方式三:
#pragma once
#ifndef __AAA__
#define __AAAE_H__
... ... // 声明、定义语句
#endif
兼而使用看起来好像身兼两者的有点,但是只有使用#ifdef就会有宏名冲突的问题,#pragma也会有不兼容的问题
转载:
http://www.cnblogs.com/jilaoyun/articles/4930789.html
http://blog.csdn.net/xhfight/article/details/51550446