为什么需要头文件? and 重定义问题

首先,我们可以将所有东西都放在一个.cpp文件内.然后编译器就将这个.cpp编译成.obj,obj是什么东西?就是编译单元了.一个程序,可 以由一 个编译单元组成,也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话,就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上就可以分别放在一个单元,也就是 cpp里面)那么就是一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序),组成一个.exe,也就是程序了.如果一 个.cpp要用到另一个.cpp定义的函数怎么办? 只需在这个.cpp种写上他的函数声明就可以了. 其余工作由链接器帮你完成,你可以随便调用该函数.链接器将所有的obj连接起来,但是如果碰巧有相同的 函数或外部变量怎么办? 他如何识别?一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名.但是值得庆幸的是,c++可以通过一种叫做链 接属性的关键字来限定,你这个函数是属于整个程序公用的,还是只是在一个编译单元obj里面使用的.这些关键字就是extern 和 static ; extern是外部链接的意思,也就是除了这个单元,外部的单元也是能够访问这个函数的.static 是内部链接,自属于自己单元.

说了这么久,还没有说.h的作用呢? 其实没有.h也能很好的工作,但是当你发现一个外部链接的函数或外部变量, 需要许多份声 明 ,因为c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译 单元,会自动从另一个编译单元那里得到什么信息,知道你是如何定义这个函数的.所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,这 样是不是很麻烦,而且,如果要修改,就必须一个一个修改. 这真让人受不了..h就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该 函数的.cpp,只需要用#include包含进去便可.以后需要修改,也只是修改一份内容.

请注意不要滥用.h,.h里面不要写代码,.h不是.cpp 的仓库,什么都塞到里面.如果在里面写代码,当其他.cpp包含他的时候, 就会出现重复定义的情况 ,比如将函数func(){printf};放到头文件 a.h,里面还有一些a.cpp需要的声明等;然后你发现b.cpp需要用到a.cpp里面的一个函数,就很高兴的将a.h包含进来.注 意,#include并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝进来.这时候实际上a.cpp和b.cpp都有一个func()函数 的定义.如果这个函数是内部链接static的话,还好,浪费了一倍空间;如 果是extern,外部链接 (这个是默认情况 ),那么根据在同一个程序内不可 出现同名函数的要求,连接器会毫不留情给你一个连接错误! ;如果你还不太理解.那么就尝试不用h,只用多个cpp看看应该如何写.尝试在两个cpp中写同 名函数.看看是否链接出错.尝试在cpp使用其他cpp定义的函数.看看应该如何做.


头文件是没有编译意义的,一般只是编译.cpp生成.obj.但是.cpp里面有#include将指定头文件(其实任何文件都行)插进来,组成完整 的.cpp.如果你不喜欢这个方式,你也可以直接在.cpp里面写好了,而不放到.h里面,再用指令拷贝进来.头文件是工具,但不是必须.

对于重定义的问题,如果在不同源文件中引用同一个头文件,为什么头文 件定义的类不会出现重定义的情况?因为不同源文件是分别编译的相互之间没有影响;    但是如果在一个源文件中重复引用同一个头文件的话就会出现重定义了;

但是对函数就不一样了,类的定义并不产生具体的代码,所以没有冲突,编译器只是需要给这个类如何分配空间,怎么访问到类成员的内存就可以了  

呵呵,类的成员函数,全局函数的代码最终会被编译成待链接的模块,连接时,连接程序通过符号表,解析出函数地址,如果解析出两个来,就不知道该链接那个了

其实只要记住:头文件不应该含有定义这一规则有三个例外:头文件可以 定义类、值在编译时就已知道的const对象和inline函数,这些实体可以在多个源文件中定义,只要每个源文件中的定义是相同的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值