正文

一个关于VC头文件的问题.2009-02-21 09:47:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/hyp1984/40985.html

分享到:

一个关于VC头文件的问题. 时间:2007-06-09 来源:开发者参考网(devtopic.com) 类别:C/C++ 内容提要:一个关于VC头文件的问题.我写了一个头文件: myhead.h然后我实现了头文件中定义的函数: myhead.cpp为什么在VC下,我在主程序中要#include myhead.h 而不是 #include myhead.cpp我的言下之意是:VC怎么找到myhead.h对应的实现myhead.cpp如果答案是同一?... 一个关于VC头文件的问题.我写了一个头文件: myhead.h然后我实现了头文件中定义的函数: myhead.cpp为什么在VC下,我在主程序中要#include "myhead.h" 而不是 #include "myhead.cpp"我的言下之意是:VC怎么找到myhead.h对应的实现myhead.cpp如果答案是同一文件名的话,那如果我不是用myhead.cpp来实现的,而是 myhead_impl.cpp来实现,VC岂不找不到了? 回复1:一般来说 XX.cpp都包含了XX.h的头文件的哒! 回复2:你的程序调用的时候只需要知道这个函数是怎么声明的就可以了但比如在链接的时候提供包含实现的obj文件或者lib文件. 回复3:cpp都会包含.h 回复4:楼主应该了解一下编译原理。简单点说,你的每一个CPP文件都会对应编译成一个.OBJ文件,你的每一个资源.rc文件会编译成一个.RES文件。最终的链接步骤就是将各个文件整合关联,并形成目标文件。C/C++语言只要求,在使用标识符前,声明过就可以。如果是函数,那么你只要在头文件里声明过就行了。具体的定义要放在.cpp中。这是因为:1.C/C++语言中的函数,声明可以有多个,但定义只能有一次。例如:void fun();void fun();void fun();void fun();void fun(){//…………}是合理的。2.我们把函数的声明放在.h中,函数的定义放在.cpp中。如果定义也放在.h中,那么多个cpp用到此函数,都包含.h就会出现重定义的问题。同理,这也是为什么我们不去包含.cpp的原因,因为那是具体的定义。例如:1.h有函数fun的声明,2.cpp和3.cpp都包含1.h,那么对应生成的2.obj和3.obj都只是包含了一句fun的标识声明。参考1的理论,这是合法的,函数可以被多次声明。但是在链接过程中,编译器要求必须能找到fun标识符的详细定义。所以你应该有一个cpp内详细定义了该函数,名字无所谓,不是必须与.h同名。这样该CPP生成的OBJ在链接期间就会被编译器检索到,并包含在目标文件内,可被同目标文件的其他位置访问到。也就是说1.h声明函数。2.cpp实现函数。3.cpp是主函数所在文件并在主函数调用该函数,那么3.cpp要求包含1.h,以便编译时刻保证该函数标识符是有效的。最终编译器只生成了2个文件,2.obj和3.obj,可以简单理解,最后的目标文件(dll或exe)就是有它们2个合并而成的。编译器会自动链接好他们的调用关系,以确保访问时的准确。 回复5:补充一句,.h文件的唯一作用就是被用来包含的。如果没有任何文件包含了一个.h,那么它就是个废物。 回复6:哈哈 今天学到咧~! 回复7:通过连接程序LINK 把你的.CPP产生的目标文件连接起来了,比如我们常用的库函数都是由LINK时装入你的.EXE文件中的 回复8:hamlet0168(铁幕诱惑) ,我问的不是你所理解的问题.大家好象也没有理解我的问题.我学过编译原理,我知道为什么要用头文件,为什么要把定义和实现分开.我问的是在VC:visual c++里面,为什么我在main函数里面#include <myhead.h>,编译器就可以自动找到myhead.h对应的实现,而这个实现名,不管我写成myhead.cpp或者myhead_impl.cpp或者是abc.cpp编译器都能找到. 回复9:编译你要明白,.h是不参与编译的.编译器会将cpp文件中包含的.h文件复制到.cpp文件里面,然后编译.cpp 也就是说编译的时候每个cpp文件都是独立的编译器为cpp文件中的函数变量名,做了一个符号表,这个符号表就存在obj文件里面.链接连接器将所编译的obj文件读取到内存中,这个时候符号和对应的函数进行合并.如果有两个obj文件中存在相同的变量符号,那么就会链接错误,变量重复定义. 回复10:首先,这个 h 和 cpp 都是在同一个工程中的,否则没有 cpp 只有 h 文件会提示找不到定义。由于在同一个工程中,那么,显然,在工程管理中会有一些信息知道工程相关的信息,这个可以理解吧?有附加信息,那么找到定义不也是很好理解的么? 回复11:似乎不领情哦:)akirya(坏[其实偶不是什么所谓的坏人]) 已经说过了函数在obj文件内,就是符号变量,当然,如果你试过__stdcall等就知道如何限制编译器为函数名定义一个何类型的符号变量了。别说一个全局函数或域函数,就算成员函数也是这样。不过似乎你想讨论的就是---1.cpp内调用fun(),那么它生成1.obj2.cpp实现fun(),那么它生成2.obj为什么编译器能准确识别到fun的实现部分,而不管它在2.cpp也好10000.cpp也好,对吧?编译器只在最后的链接步骤里才将全部的obj组合起来的,当然这里面细节也很多。能理解吗?所有obj最后都合并了,也就是说,所有的函数定义和调用都在一起了,大家一眼就能望见彼此,当然找的到了…………你在myhead.h中声明一个函数,但从不调用它,也不去实现它,你看看出错不。反过来,你声明了也调用了,但没有实现,仔细看编译的错误提示,正在编译XX.cpp正在编译XXX.cpp正在链接…………那错误是什么?因为编译器在最后的未定位机器语言文件中找不到该符号变量了。因为任何一个obj里面都没这个符号变量。sorry,罗嗦了这么多。关于头文件,仔细看看前几位的回复吧。别露掉任何一个字。尤其是楼上2位的。<myhead.h>你完全可以不#include 的,自己把声明写进去也行----如果你愿意这么做。你看过编译原理?但愿你不是只看过第一章。唉,怪我气胜,见笑:) 回复12:学习了 ~ 回复13:To :hamlet0168(铁幕诱惑) 谢谢你的耐心讲解,看来的得再看看编译原理.谢谢你们! 回复14:突然还想问一句,如果一个头文件有两个实现的CPP文件允许吗? 回复15:当然 ...h 和 cpp 并没有直接联系 ...

阅读(3089) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册