C头文件问题
我在使用类时尝试了一些c代码,这个问题发生在我身上,这让我感到烦恼.
我创建了一个包含我的类定义的头文件和一个包含该实现的cpp文件. 如果我在不同的cpp文件中使用此类,为什么我要包含头文件而不是包含类实现的cpp文件? 如果我包含类实现文件,那么应该自动导入类头文件(因为我已经将头文件包含在实现文件中)?这不是更自然吗? 对不起,如果这是一个愚蠢的问题,我真的很有兴趣知道为什么大多数人包括.h而不是.cpp文件,当后者看起来更自然时(我知道python有点,也许这就是为什么它至少对我来说似乎很自然).它只是历史还是有关于计划组织的技术原因还是其他什么? 解决方法
因为在编译另一个文件时,C实际上并不需要知道实现.它只需要知道每个函数的签名(它需要的参数和它返回的内容),每个类的名称,#defined的宏和其他“摘要”信息,以便它可以检查你的’正确使用函数和类.在链接器运行之前,不会将不同.cpp文件的内容放在一起.
例如,假设你有foo.h int foo(int a,float b); 和foo.cpp #include "foo.h" int foo(int a,float b) { /* implementation */ } 和bar.cpp #include "foo.h" int bar(void) { int c = foo(1,2.1); } 当你编译foo.cpp时,它变成了foo.o,当你编译bar.cpp时,它变成了bar.o.现在,在编译过程中,编译器需要检查foo.cpp中函数foo()的定义是否与bar.cpp中函数foo()的用法一致(即取一个int和一个float并返回一个int ).它的方式是让你在两个.cpp文件中都包含相同的头文件,如果定义和用法都与头文件中的声明一致,那么它们必须相互一致. 但是编译器实际上并没有在bar.o中包含foo()的实现.它只包含一个汇编语言指令来调用foo.所以当它创建bar.o时,它不需要知道任何关于foo.cpp的内容.但是,当你进入链接阶段(在编译之后发生)时,链接器实际上需要知道foo()的实现,因为它将在最终程序中包含该实现并用一个call foo指令替换调用0x109d9829(或者它决定函数foo()的内存地址应该是什么). 请注意,链接器不检查foo()(在foo.o中)的实现是否与foo()的使用一致(在bar.o中) – 例如,它不检查foo()是否被调用使用int和float参数!使用汇编语言进行这种检查很困难(至少比检查C源代码更难),因此链接器依赖于知道编译器已经检查过它.这就是为什么你需要头文件来向编译器提供这些信息的原因. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- react-native学习——SVN管理项目源码
- jackson和fastjson的效率对比:
- swift 图片压缩
- c# – NHibernate – NHibernate.Exceptions.GenericADOExc
- 使用Tuxedo将C语言中的结构体转换成Xml格式的字符串
- ruby-on-rails – bundle install导致git clone错误.不确定
- arcgis for flex api version3.7 教程:3.如何使用QueryTas
- C语言中获取和改变目录的相关函数总结
- Data Guard Physical Standby Setup Using the Data Guard
- 最全的常用正则表达式大全——包括校验数字、字符、一些特殊