一般类定义都会放在头文件中。头文件一般包含类的定义、extern关键字的声明和函数的声明。
头文件的好处:1. 保证所有文件使用给定实体的同一声明;2. 当声明需要修改时,只要头文件需要更新。
1. 头文件用于声明而不是用于定义
记住定义和声明的区别对于定义头文件是很重要的。定义只可出现一次,而声明则可出现多次。
同一个程序中有两个以上文件含有相同定义都会导致多重定义连接错误。因为头文件包含在多个源文件中,所以不应该含有变量和函数的定义。
但是对于对于头文件不应包含定义这一规则,有3个例外:1. 头文件可以定义类;2. 值在编译时就知道的const对象;3. inline函数
对于类定义可以放在头文件中,因为编译器需要知道组成该类型的数据成员和在这些对象上执行的操作来产生相应的代码。
2. 一些const对象定义在头文件中
在const限定符中说过,const变量默认是定义该变量的文件的局部变量。这样设置默认情况的原因是允许const变量定义在头文件中。
在c++程序中,有些地方需要放置常量表达式。例如枚举成员的初始化必须是常量表达式。常量表达式是编译器在编译时就能计算出来的表达式。当const 整型变量通过常量表达式自我初始化时,这个const整型变量就可能是常量表达式。而const变量要成为常量表达式,初始化必须为编译器可见。为让多个文件使用相同的常量值,const变量和它的初始化必须是每个文件都可见的。而要是初始化式可见,一般都把这样的const变量定义在头文件中。
但是,c++中的任何变量都只能定义一次。定义会分配存储空间,而所有对该变量的使用都关联到同一个存储空间。因为const对象默认为定义它的文件的局部变量,所以把他们定义在头文件中是合法的。
这种行为有一种重要的含义:当我们在头文件中定义了const变量后,每个包含该头文件的源文件都有了自己的const变量,其名称和值都一样。
//initConstFunc.cpp int initConst() //用于初始化.h文件的const变量 { return 8; }
//headerWithCosnt.h extern int initConst(); //初始化const变量函数 const int constVal = initConst();
//headerTest.cpp #include<iostream> #include"headerWithConst.h" using namespace std; int main() { cout<<constVal<<" in ht1"<<endl; //输出.h 文件中的const变量 extern int main2(); main2(); return 0; }
//headerTest2.cpp #include<iostream> #include"headerWithConst.h" using namespace std; int main2() { cout<<constVal<<" in ht2"<<endl; return 0; }
运行结果:
可以看到:在.cpp文件中全局范围定义的非const变量或函数,其作用范围是整个程序 ,只要在另一个文件中用extern声明,就可直接使用;对于在.h文件中定义的const变量,其默认作用域范围是该文件的局部作用域,因此可以定义在.h文件中,而其他多个文件包含该.h文件则不会出错。