biGpython

生亦何欢,死亦何苦? 予我長袖,我必善舞!

导航

cpp文件和h文件的区别

C++里面编译的单位是compile unit,也就是经过预处理之后的源文件,这包括宏的处理,以及include文件的替换等。

一般来说,h文件用于函数和变量的声明,而cpp文件则用于定义。

对于C++编译环境而言,他们都不过是操作系统内的文件,h文件可以include cpp文件,cpp文件也可以include h文件

他们的区别是人们在编译/链接过程中为了方便的强加进去的。

单个的h文件也可以作为一个compile unit,但是如果h文件里面没有函数定义,那么译器除了解析一遍函数原型,什么都干不了,不会生成对应的目标代码;

如果h文件里面包含函数定义,这又分两种:内联函数和非内联函数。下面分别讨论:

1)内联函数

对于内联函数,编译器会“尽量”将其每次调用使用其目标代码替换;

注:对于内联函数的处理,主要有两种:编译期处理和链接期处理。

如果是编译期的处理,那么显然编译器在每次该函数调用的时候必须能够知道该函数的定义才能替换,

此一般是通过写在h文件中,这样可以被包含进每个编译单元;如果是链接期的处理,理论上说可以放在cpp文件,

然后由链接器将对其的调用替换成其定义。跟模板的实例化一样,目前的编译器一般都是采用的第一种方式,也就是编译期的处理。

因此内联函数和模板一般都要在h文件中定义。

2)非内联函数

对于非内联函数,定义必须放在cpp文件。否则,如果在h文件中定义,如果这个h文件被两个compile unit包含,则会生成该函数的两份定义,

这样链接的时候,就会出现重复的定义了。对于cpp文件,一般用于函数/变量的定义。但是在函数的实现过程中,会对其他的函数/变量进行应用,

这时就需要包含相应的h文件,告诉编译器这些函数/变量的原型是什么,至于这些函数/变量究竟是什么内容,放在什么位置,则是联接器关心的事情。

对于这种编译模型,h文件由于会被include在多个cpp文件中,因此可能会经过多次编译,这时候就要注意符号的重复定义问题;

对于cpp文件,一般只会编译一次,不会存在上述重复定义的问题。(当然,也可以对cpp文件编译两次,如g++ -c test.cpp -o test1.o, g++ -c test.cpp -o test2.o,

那么如果test1.o test2.o同时链接进最后的库/程序时,就会出现重复定义的链接错误了。

posted on 2012-01-08 10:22  biGpython  阅读(3487)  评论(0编辑  收藏  举报