原网址:http://www.cnblogs.com/zjfdlut/archive/2010/11/13/1876409.html
个人菜鸟,发表下对头文件包含顺序的看法:
首先是常规的包含:
1
#include
"
a.h
"
2
3
int
4
main()
5
{
6
function_a();
7
}
这是一个在平常不过的包含了,主文件main.cpp包含头文件"a.h",当调用function_a()函数时,由于main.cpp
文件中未包含function_a此函数的声明,那么它会到"a.h"这个文件中去找它的声明。如果在"a.h"这个文件中找不到,
那么它回到"a.h"所包含的头文件中去找,这样一级一级往上找,直到找到或者找不到而报错为止。
图中是最为平常的头文件包含。
但是当我在看STL的源代码时却发现了问题,比如stl_vector.h这个文件中的一段代码:
代码
1
template
<
class
_Tp,
class
_Alloc
>
2
void
vector
<
_Tp, _Alloc
>
::_M_fill_insert(iterator __position, size_type __n,
3
const
_Tp
&
__x)
4
{
5
if
(__n
!=
0
) {
6
if
(size_type(_M_end_of_storage
-
_M_finish)
>=
__n) {
7
......
8
fill(__position, __position
+
__n, __x_copy);
9
}
10
else
{
11
......
15
fill(__position, __old_finish, __x_copy);
16
}
17
}
代码中有一个fill函数,但是stl_vector.h这个文件中却没有包含这个函数的实现,当我查找其所包含头文件时,却
发现也没有包含这个函数的其它头文件,这时怎么回事呢,当我们想使用该头文件是编译器岂不是回报错?
确实,如果我们直接包含该头文件,编译起将会报fill函数未定义的错误,那么到底是怎么回事呢?
当我们查看vector这个文件时,真相大白:
显然stl_vector.h文件被包含在vector之中,注意在stl_algobase.h文件中包含了fill的实现:
stl_algobase.h
template
<
class
_ForwardIter,
class
_Tp
>
void
fill(_ForwardIter __first, _ForwardIter __last,
const
_Tp
&
__value) {
__STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
for
( ; __first
!=
__last;
++
__first)
*
__first
=
__value;
}
fill这个函数在stl_algobase.h这个文件中。所以当我们在程序中写诸如:
#include
<
vector
>
int
main()
{
std::vector<int> vec;
}
这种代码时才不会报fill未找到的错误。但如果我们把vector文件中的包含顺寻更改如下:
1
#ifndef __SGI_STL_VECTOR
2
#define
__SGI_STL_VECTOR
3
......
4
#include
<
stl_vector.h
>
5
#include
<
stl_algobase.h
>
6
时,那就错了,为什么,因为stl_algobase.h文件包含在stl_vector.h之后,fill函数的实现在stl_vector.h
文件中将不可见!
结论:
1.头文件的包含必须严格按照顺序,否则结果将难以预料!
2.你不应该直接使用stl_vector.h文件,而应该使用vector头文件!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)