C++ Primer 学习笔记:头文件的使用小结
2009-07-03 17:55
573 查看
头文件不宜太大
编译头文件需要一定的时间。如果头文件太大,程序员可能不愿意承受包含该头文件所带来的编译时代价。
头文件用于声明而不是用于定义
定义只可以出现一次,而声明则可以出现多次,所以如下所示的定义不应该放在头文件里:
extern int ival = 10; // initializer, so it's a definition
double fica_rate; // no extern, so it's a definition
const 对象定义在头文件中
const 对象定义在头文件中,同一个头文件可能在程序中出现多次,所以同一个const对象可能在同一个程序
中出现多次,这是合法的,原因:
const 变量默认时是定义该变量的文件的局部变量。因此,同一个const对象可以出现在同一个程序的不同文件中
(当然,如果在同一个文件中重复出现多次是不允许的!)
注意:
当我们在头文件中定义了 const 变量后,每个包含该头文件的源文件都有了自己的 const 变量,其名称和值都一样。
在实践中,大部分的编译器在编译时都会用相应的常量表达式替换这些 const 变量的任何使用。所以,在实践中不会有任何存储空间用于存储用常量表达式初始化的 const 变量。
如果 const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义。相反,和其他的变量一样,该 const 变量应该在一个源文件中定义并初始化。应在头文件中为它添加 extern 声明,以使其能被多个文件共享。
头文件使用:
如果头文件名括在尖括号(< >)里,那么认为该头文件是标准头文件。如:
#include <standard_header>
编译器将会在预定义的位置集查找该头文件,预定义的位置通过查阅编译器用户指南等方式确认。
如果头文件名括在一对引号里,那么认为它是非系统头文件。如:
#include "my_file.h"
非系统头文件的查找通常开始于源文件所在的路径。
预处理器:
预处理器处理程序的源代码,在编译器之前运行。#include是一种预处理指令。
多重包含问题和解决:
头文件经常 #include 其他头文件。一个头文件被多次包含进同一源文件也很常见。
如果同一头文件被多次包含,就可能导致该头文件中的变量和函数等被多次定义。
(不提倡在头文件中定义除const以外的变量和函数,但是有的头文件确实包含不合适的定义)
而在同一文件中重复定义是非法的。
必须保证多次包含同一头文件时不会引起在该头文件中定义的类,对象,变量,函数被重复定义。
这样,我们设计的头文件就可以多次包含在同一源文件中了。
具体的解决方案:使用预处理器定义头文件保护符,
头文件保护符用于避免在已经见到头文件的情况下重新处理该头文件的内容。
头文件保护符其实是一种预处理器变量
预处理器变量有两种状态:已定义或未定义。
使用#define可以使预处理器变量成为已定义状态,而在此之前预处理器变量处于未定义状态。
相应的,可以使用。#ifndef 指示检测指定的预处理器变量是否未定义。
可以通过检测预处理器变量(头文件保护符)是否已定义来解决多重包含问题,示例代码:
第1次处理头文件时:
#ifndef SALESITEM_H // 测试会成功,因为 SALESITEM_H 还未定义。
#define SALESITEM_H // 定义SALESITEM_H
// 类,对象,变量,函数等被定义
#endif
第2次处理头文件时:
#ifndef SALESITEM_H // 测试会失败,因为 SALESITEM_H 已定义。
#define SALESITEM_H // 不会再次定义 SALESITEM_H
// 类,对象,变量,函数等不会被再次定义,从而避免了重复定义
#endif
预处理器变量命名:
预处理器变量 的名字在程序中必须是唯一的。为了避免名字冲突,预处理器变量经常用全大写字母表示。
也可以使用类名等来命名预处理器变量来避免重名,如一个头文件中定义了类Sales_item,则
可以这样处理头文件:
#ifndef SALESITEM_H
#define SALESITEM_H
class Sales_item {
... ... ...
}
#endif
因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。
编译头文件需要一定的时间。如果头文件太大,程序员可能不愿意承受包含该头文件所带来的编译时代价。
头文件用于声明而不是用于定义
定义只可以出现一次,而声明则可以出现多次,所以如下所示的定义不应该放在头文件里:
extern int ival = 10; // initializer, so it's a definition
double fica_rate; // no extern, so it's a definition
const 对象定义在头文件中
const 对象定义在头文件中,同一个头文件可能在程序中出现多次,所以同一个const对象可能在同一个程序
中出现多次,这是合法的,原因:
const 变量默认时是定义该变量的文件的局部变量。因此,同一个const对象可以出现在同一个程序的不同文件中
(当然,如果在同一个文件中重复出现多次是不允许的!)
注意:
当我们在头文件中定义了 const 变量后,每个包含该头文件的源文件都有了自己的 const 变量,其名称和值都一样。
在实践中,大部分的编译器在编译时都会用相应的常量表达式替换这些 const 变量的任何使用。所以,在实践中不会有任何存储空间用于存储用常量表达式初始化的 const 变量。
如果 const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义。相反,和其他的变量一样,该 const 变量应该在一个源文件中定义并初始化。应在头文件中为它添加 extern 声明,以使其能被多个文件共享。
头文件使用:
如果头文件名括在尖括号(< >)里,那么认为该头文件是标准头文件。如:
#include <standard_header>
编译器将会在预定义的位置集查找该头文件,预定义的位置通过查阅编译器用户指南等方式确认。
如果头文件名括在一对引号里,那么认为它是非系统头文件。如:
#include "my_file.h"
非系统头文件的查找通常开始于源文件所在的路径。
预处理器:
预处理器处理程序的源代码,在编译器之前运行。#include是一种预处理指令。
多重包含问题和解决:
头文件经常 #include 其他头文件。一个头文件被多次包含进同一源文件也很常见。
如果同一头文件被多次包含,就可能导致该头文件中的变量和函数等被多次定义。
(不提倡在头文件中定义除const以外的变量和函数,但是有的头文件确实包含不合适的定义)
而在同一文件中重复定义是非法的。
必须保证多次包含同一头文件时不会引起在该头文件中定义的类,对象,变量,函数被重复定义。
这样,我们设计的头文件就可以多次包含在同一源文件中了。
具体的解决方案:使用预处理器定义头文件保护符,
头文件保护符用于避免在已经见到头文件的情况下重新处理该头文件的内容。
头文件保护符其实是一种预处理器变量
预处理器变量有两种状态:已定义或未定义。
使用#define可以使预处理器变量成为已定义状态,而在此之前预处理器变量处于未定义状态。
相应的,可以使用。#ifndef 指示检测指定的预处理器变量是否未定义。
可以通过检测预处理器变量(头文件保护符)是否已定义来解决多重包含问题,示例代码:
第1次处理头文件时:
#ifndef SALESITEM_H // 测试会成功,因为 SALESITEM_H 还未定义。
#define SALESITEM_H // 定义SALESITEM_H
// 类,对象,变量,函数等被定义
#endif
第2次处理头文件时:
#ifndef SALESITEM_H // 测试会失败,因为 SALESITEM_H 已定义。
#define SALESITEM_H // 不会再次定义 SALESITEM_H
// 类,对象,变量,函数等不会被再次定义,从而避免了重复定义
#endif
预处理器变量命名:
预处理器变量 的名字在程序中必须是唯一的。为了避免名字冲突,预处理器变量经常用全大写字母表示。
也可以使用类名等来命名预处理器变量来避免重名,如一个头文件中定义了类Sales_item,则
可以这样处理头文件:
#ifndef SALESITEM_H
#define SALESITEM_H
class Sales_item {
... ... ...
}
#endif
因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。
相关文章推荐
- C++ Primer学习笔记:字面值常量使用小结
- C++ Primer学习笔记:算术类型使用小结
- C++ Primer学习笔记:变量使用小结
- 学习笔记----C++ 中iomanip头文件的使用
- C++ Primer 学习笔记与思考_7 void和void*指针的使用方法
- Spring学习笔记之RestTemplate使用小结
- C++ Primer 学习笔记(1)——vector的使用方法
- C++ Primer学习笔记:类定义和使用
- 【C++ Primer学习笔记】为类的成员使用类声明
- iOS学习笔记24-iOS7 StatusBar 使用小结
- C++ primer 学习笔记(一个学过谭老师的C++书籍, 并在一年间间断使用过C++的码农)
- C++ Primer学习笔记:引用的使用注意事项
- C++ Primer学习笔记:C++ 常用标准类型小结
- python学习笔记:datetime使用小结
- c#学习笔记之九 事件(event)的使用,一个简单的例子揭示其设计理念
- C++ Primer复习和学习笔记 第十三章 复制控制
- php学习笔记五:使用 xampp 部署多个站点
- entityframework学习笔记--003-使用model first
- 我的嵌入式学习笔记(2)--scanf使用常见问题及解决方法
- JSTL学习笔记3-----URL相关标签的使用